是否有可能防止SQL注入在Node.js的(最好用模块)中相同的方式,PHP有这样对他们的保护,预处理语句。
如果是这样,怎么样? 如果不是,有一些可能会绕过我提供的代码示例 (见下文)。
一些背景:
我正在使用的包括Node.js的+ MYSQL的后端协议栈的Web应用程序节点MySQL的模块。 从可用性的角度来看,该模块是伟大的,但还没有付诸实施PHP的一个类似于预处理语句 (虽然我知道它是在待办事项 )。
从我的理解,PHP的实现准备好的声明,除其他事项外, 大大有助于预防SQL注入的。 我很担心,虽然,我的Node.js应用程序可能是开放的类似的攻击, 甚至与字符串转义默认提供的 (如下面的代码片段)。
节点的MySQL似乎是node.js的最流行的MySQL连接器,所以我想知道其他人可能会做(如果有的话),以考虑这个问题 - 或者如果它甚至node.js的开始与问题(不知道如何做到这一点不应该,因为用户/客户端输入参与)。
我应该切换到节点的MySQL原生暂时的,因为它确实提供了预处理语句? 我犹豫要做到这一点,因为它似乎并不像节点MySQL作为活跃(尽管这可能只是意味着它是完整的)。
下面是用户注册代码,它使用一个片段消毒剂模块,与节点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本地的,所以我不建议切换到节点的mysql本地 。 该文件指出转义下列准则:
编辑: 节点MySQL的原生也是一个纯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的预处理语句。
该准备的语句是在待办事项此连接器列表中,但该模块至少允许您指定自定义格式,可以是非常相似的预处理语句。 下面是自述的例子:
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");
我意识到这是一个老的文章,但似乎是一个答案从来没有标记,所以我会扔了这一点那里。
在关于测试,如果你利用模块是安全的或不存在,你可以采取几种途径。 我将涉及每个优点/缺点,因此您可以做出更明智的决策。
目前,有不适合你正在使用的模块的任何安全漏洞,但是,这往往会导致安全的错觉,因为很好可能是一个漏洞利用目前正在使用的模块/软件包,你不会被警告直到供应商的问题适用于修复/补丁。
为了及时了解安全漏洞的,你需要按照邮件列表,论坛,IRC和其他黑客相关的讨论。 PRO:可很多时候,你将供应商已被惊动或已经发布了修复/补丁来弥补攻击的潜在途径对他们的软件之前意识到库中潜在的问题。 CON:这可能是非常耗时和资源密集。 如果你使用的RSS提要走这条路僵尸,日志分析(IRC聊天记录),并使用或关键短语的web刮板(在这种情况下,节点的MySQL原生)和通知可以帮助减少花费的时间曳这些资源。
创建一个模糊器,使用模糊器或其他漏洞的框架,如Metasploit的 , SQLMAP等,以帮助测试的问题,供应商可能没有找。 PRO:这可以被证明是确保你正在实施的模块/软件是否是供公众查阅安全可接受的水平确保消防方法。 CON:这也成为耗时和昂贵的。 另一个问题将源于误报以及其中的问题所在,但没有注意到的结果没有受过教育的审查。
真的一般安全和应用安全性是非常耗费时间和资源。 有一件事经理总是使用一个公式来确定实施上述两个方案的成本效益(人力,物力,时间,支付等)。
不管怎么说,我知道这是不是一个“是”或“否”的回答可能一直希望,但我不认为任何人都可以给你,直到他们执行有问题的软件进行分析。
我知道,这个问题是旧的,但对于有兴趣的人,Mysql的母语已经过时,因此成为MySQL2是与原来的MySQL模块的团队的帮助下创建一个新的模块。 该模块具有更多的功能,我认为它有你想要的东西,因为它有预处理语句(由using.execute())像PHP更多的安全性。
它也非常活跃(在过去的变化是从2-1天)之前我没有尝试,但我认为这是你想要的东西多。
最简单的方法是处理所有你导出到你的路由其自身的模块在你的数据库交互。 如果你的路线有没有数据库的情况下则SQL也看不动它。