是否有可能阻止Node.js中的SQL注入(最好使用模块),就像PHP具有保护它们的Prepared Statements一样。
如果是这样,怎么样?如果没有,可能会绕过我提供的代码的一些示例(见下文)。
某些情境:
我正在使用node-mysql模块创建一个包含Node.js + MySql的后端堆栈的Web应用程序。从可用性的角度来看,该模块很棒,但它还没有实现类似于PHP Prepared Statements的东西(尽管我知道它在todo上)。
根据我的理解,PHP在预防SQL注入方面实现了预准备语句,helped greatly等。不过我很担心我的node.js应用可能会受到类似攻击even with the string escaping provided by default(如下面的代码段所示)。
node-mysql似乎是node.js最受欢迎的mysql连接器,所以我想知道其他人可能正在做什么(如果有的话)来解决这个问题 - 或者甚至是node.js的问题开头(不知道这不会是什么,因为涉及用户/客户端输入)。
我应该暂时切换到node-mysql-native,因为它确实提供了准备好的语句吗?我对此犹豫不决,因为它似乎不像节点那样活跃-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?
});
答案 0 :(得分:49)
node-mysql
库会在您正在使用时自动执行转义。见https://github.com/felixge/node-mysql#escaping-query-values
答案 1 :(得分:10)
图书馆有关于转义的自述文件中有section。它是Javascript原生的,所以我不建议切换到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的准备语句。
准备好的语句位于此连接器的todo列表中,但此模块至少允许您指定与预准备语句非常相似的自定义格式。以下是自述文件中的一个示例:
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");
答案 2 :(得分:10)
我意识到这是一个较旧的帖子,但似乎答案从未标记过,所以我会把它扔出去。
关于测试您使用的模块是否安全,您可以采取多种途径。我会谈谈每个人的利弊,以便你做出更明智的决定。
目前您正在使用的模块没有任何漏洞,但是,这通常会导致错误的安全感,因为当前正在利用您正在使用的模块/软件包的漏洞很可能并且您不会在供应商应用修补程序/修补程序之前,系统会发出问题警告。
要及时了解漏洞,您需要关注邮件列表,论坛,IRC&其他与黑客相关的讨论。 专业版:在供应商收到警报或已发布修复程序/修补程序以补救其软件的潜在攻击途径之前,您经常会发现库中存在潜在问题。 CON:这可能非常耗时且资源密集。如果您使用RSS源,日志解析(IRC聊天日志)和/或使用关键短语(在本例中为node-mysql-native)的网络剪贴板,并且通知可以帮助减少用于控制这些资源的时间。
创建模糊器,使用fuzzer或其他漏洞框架,例如metasploit,sqlMap等,以帮助测试供应商可能未查找的问题。 PRO:这可以证明是一种确保可接受水平的确定的火灾方法,无论您实施的模块/软件是否对公共访问是安全的。 CON:这也变得耗时且昂贵。另一个问题将来自误报以及对问题所在但没有注意到的结果的未经教育的审查。
真正的安全性和应用程序安全性通常非常耗时且资源密集。管理者将始终使用的一件事是确定执行上述两种选择的成本效益(人力,资源,时间,工资等)的公式。
无论如何,我意识到这不是一个可能一直希望的“是”或“否”的答案,但我认为在他们对相关软件进行分析之前,任何人都不能给你这个答案。
答案 3 :(得分:1)
我知道这个问题很旧,但是对于任何感兴趣的人,Mysql原生版本已经过时,因此它变成了MySQL2,这是在原始MySQL模块团队的帮助下创建的新模块。该模块具有更多功能,我想它具有所需的功能,因为它已经准备好了语句(通过使用.execute()),如PHP中那样,可以提高安全性。
它也非常活跃(最后一次更改是2-1天),我之前没有尝试过,但我想这是您想要的,并且更多。
答案 4 :(得分:0)
在本文中您可以找到针对注入、xss 和蛮力攻击的简单解决方案 How to secure your node app from attacks
答案 5 :(得分:-1)
最简单的方法是在您导出到路由的模块中处理所有数据库交互。如果您的路由没有数据库的上下文,那么SQL无论如何都无法触摸它。