簡體   English   中英

防止SQL注入Node.js

[英]Preventing SQL injection in Node.js

是否有可能以與 PHP 具有防止它們的准備語句相同的方式在 Node.js(最好使用模塊)中防止 SQL 注入。

如果是這樣,如何? 如果不是,有哪些示例可能會繞過我提供的代碼(見下文)。


一些背景:

我正在使用node-mysql模塊制作一個 web 應用程序,其后端堆棧由 Node.js + MySql 組成。 從可用性的角度來看,該模塊很棒,但它還沒有實現類似於 PHP 的Prepared Statements的東西(盡管我知道它在todo上)。

根據我的理解,PHP 對准備好的語句的實現,除其他外, 極大地幫助了 SQL 注入的預防。 不過,我擔心我的 node.js 應用程序可能會受到類似的攻擊,即使默認提供字符串 escaping (如下面的代碼片段所示)也是如此。

node-mysql 似乎是 node.js 最受歡迎的 mysql 連接器,所以我想知道其他人可能正在做什么(如果有的話)來解決這個問題 - 或者它是否甚至是 node.js 的問題(不知道如何這不會,因為涉及用戶/客戶端輸入)。

我應該暫時切換到node-mysql-native嗎,因為它確實提供了准備好的語句? 我很猶豫要不要這樣做,因為它似乎不像 node-mysql 那樣活躍(盡管這可能只是意味着它是完整的)。

下面是一段用戶注冊代碼,它使用sanitizer模塊,以及 node-mysql 准備好的類似語句的語法(正如我上面提到的,進行字符轉義),分別防止跨站點腳本和 sql 注入:

// Prevent xss
var clean_user = sanitizer.sanitize(username);

// assume password is hashed already
var post = {Username: clean_user, Password: hash};

// This just uses connection.escape() underneath
var query = connection.query('INSERT INTO users SET ?', post,
   function(err, results)
   {
       // Can a Sql injection happen here?
   });

node-mysql庫在您使用時會自動執行轉義。 https://github.com/felixge/node-mysql#escaping-query-values

該庫在自述文件中有一個關於轉義的部分 它是 Javascript-native,所以我不建議切換到node-mysql-native 該文檔說明了這些轉義准則:

編輯: node-mysql-native也是一個純 Javascript 解決方案。

  • 數字保持不變
  • 布爾值轉換為true / false字符串
  • 日期對象轉換為YYYY-mm-dd HH:ii:ss字符串
  • 緩沖區被轉換為十六進制字符串,例如X'0fa5'
  • 字符串被安全轉義
  • 數組變成列表,例如['a', 'b']變成'a', 'b'
  • 嵌套數組變成分組列表(用於批量插入),例如[['a', 'b'], ['c', 'd']]變成('a', 'b'), ('c', 'd')
  • 對象變成key = 'val'對。 嵌套對象被轉換為字符串。
  • undefined / null被轉換為NULL
  • NaN / Infinity保持原樣。 MySQL 不支持這些,並且嘗試將它們作為值插入將觸發 MySQL 錯誤,直到它們實現支持。

這允許您執行以下操作:

var userId = 5;
var query = connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
  //query.sql returns SELECT * FROM users WHERE id = '5'
});

還有這個:

var post  = {id: 1, title: 'Hello MySQL'};
var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
  //query.sql returns INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
});

除了這些函數,您還可以使用轉義函數:

connection.escape(query);
mysql.escape(query);

要轉義查詢標識符:

mysql.escapeId(identifier);

作為對您對准備好的陳述的評論的回應:

從可用性的角度來看,這個模塊很棒,但它還沒有實現類似於 PHP 的 Prepared Statements 的東西。

准備好的語句在此連接器的待辦事項列表中,但此模塊至少允許您指定與准備好的語句非常相似的自定義格式。 這是自述文件中的一個示例:

connection.config.queryFormat = function (query, values) {
  if (!values) return query;
  return query.replace(/\:(\w+)/g, function (txt, key) {
    if (values.hasOwnProperty(key)) {
      return this.escape(values[key]);
    }
    return txt;
  }.bind(this));
};

這會更改連接的查詢格式,因此您可以使用如下查詢:

connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
//equivalent to
connection.query("UPDATE posts SET title = " + mysql.escape("Hello MySQL");

關於測試您正在使用的模塊是否安全,您可以采取多種途徑。 我將討論每種方法的優缺點,以便您做出更明智的決定。

目前,您正在使用的模塊沒有任何漏洞,但是,這通常會導致錯誤的安全感,因為目前很可能存在漏洞正在利用您正在使用的模塊/軟件包,而您不會在供應商應用修復程序/補丁之前收到問題警報。

  1. 為了及時了解漏洞,您需要關注郵件列表、論壇、IRC 和其他與黑客相關的討論。 專業人士:您經常會在供應商收到警報或發布修復/補丁以修復對其軟件的潛在攻擊途徑之前意識到庫中的潛在問題。 CON:這可能非常耗時且占用大量資源。 如果您確實使用 RSS 提要、日志解析(IRC 聊天日志)和/或使用關鍵短語(在本例中為 node-mysql-native)和通知的網絡爬蟲程序,可以幫助減少花費在這些資源上的時間。

  2. 創建一個 fuzzer,使用一個fuzzer或其他漏洞框架,如metasploitsqlMap等來幫助測試供應商可能沒有尋找的問題。 PRO:這可以證明是確保您正在實施的模塊/軟件對於公眾訪問是安全的達到可接受水平的可靠方法。 CON:這也變得耗時且昂貴。 另一個問題將源於誤報以及對存在問題但未被注意到的結果的未受過教育的審查。

真正的安全性和一般的應用程序安全性可能非常耗時且資源密集。 管理人員將始終使用的一件事是確定執行上述兩個選項的成本效益(人力、資源、時間、薪酬等)的公式。

無論如何,我意識到這不是可能一直希望的“是”或“否”答案,但我認為在他們對相關軟件進行分析之前,任何人都不能給你這個答案。

Mysql-native 已經過時,所以它變成了 MySQL2 ,這是一個在原始 MySQL 模塊團隊的幫助下創建的新模塊。 這個模塊有更多的特性,我認為它有你想要的,因為它已經准備了語句(通過 using.execute()),就像在 PHP 中一樣,以提高安全性。

它也非常活躍(最后一次更改是 2-1 天)我之前沒有嘗試過,但我認為這是你想要的,還有更多。

防止 SQL 注入

SQL 注入是一種常見的網絡黑客技術,用於破壞或濫用您的數據庫。 為防止 SQL 注入,當查詢值是用戶提供的變量時,應使用轉義值。

使用 mysql.escape() 方法轉義查詢值:

var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ' + mysql.escape(adr);
con.query(sql, function (err, result) {
  if (err) throw err;
  console.log(result);
});

使用占位符轉義查詢值? 方法:

var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ?';
con.query(sql, [adr], function (err, result) {
  if (err) throw err;
  console.log(result);
});

更多詳情

在本文中,您可以找到針對注入、xss 和蠻力攻擊的簡單解決方案如何保護您的節點應用程序免受攻擊

最簡單的方法是在導出到路由的自己的模塊中處理所有數據庫交互。 如果您的路線沒有數據庫的上下文,那么 SQL 無論如何都無法觸及它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM