如何防止 JavaScript NoSQL 注入 MongoDB?
我正在开发一个 Node.js 应用程序,我正在将req.body
json 对象传递给猫鼬模型的保存函数。我以为幕后有保障措施,但事实并非如此。
如何防止 JavaScript NoSQL 注入 MongoDB?
我正在开发一个 Node.js 应用程序,我正在将req.body
json 对象传递给猫鼬模型的保存函数。我以为幕后有保障措施,但事实并非如此。
Sushant的回答不正确。您需要了解 MongoDB 中的 NoSQL 注入。
示例(取自此处)
User.findOne({
"name" : req.params.name,
"password" : req.params.password
}, callback);
如果req.params.password
是{ $ne: 1 }
,将在不知道密码的情况下检索用户($ne
表示不等于 1)。
MongoDB 驱动程序
您可以使用mongo-sanitize:
它将删除输入中以“$”开头的所有键,因此您可以将其传递给 MongoDB,而不必担心恶意用户覆盖。
var sanitize = require('mongo-sanitize');
var name = sanitize(req.params.name);
var password = sanitize(req.params.password);
User.findOne({
"name" : name,
"password" : password
}, callback);
猫鼬司机
由于它遵循模式,如果密码是字符串字段,它会将对象转换{ $ne: 1 }
为字符串,并且不会造成任何损坏。在这种情况下,您不需要清理,只需记住设置适当的架构。
尽管帖子已过时,但我正在回答。
我知道三种方法。
第一:有一个多用途的内容过滤器。还通过过滤方式提供MongoDB注入保护。
第二: mongo-sanitize,帮助清理 mongodb 查询以防止查询选择器注入。
第三:我在这里看到了这个也可以应用于 MongoDB 的解决方案。实现起来真的很简单。仅使用 JavaScript 的内置escape()
函数。
escape()
将字符串转换为ascii
代码。$ne
被转换为%24ne
.
var privateKey = escape(req.params.privateKey);
App.findOne({ key: privateKey }, function (err, app) {
//do something here
}
为了防止来自具有未知结构的数据对象的查询选择器注入
使用 mongo-sanitize 通过递归进行深度清理:
const deepSanitize = (value) => {
if(Array.isArray(value)){
value.forEach(elm=>deepSanitize(elm))
}
if(typeof(value) === 'object' && value !== null){
Object.values(value).forEach((elm)=>{
deepSanitize(elm)
})
}
return sanitize(value)
}
例如,sanitize(req.query)
嵌套查询选择器将不会被删除:
const req = {}
req.query = { _id : { $ne: 1 } }
console.log(req.query)) // { _id: { '$ne': 1 } }
console.log(sanitize(req.query)) // { _id: { '$ne': 1 } }
使用deepSanitize(req.query)
净化过的对象(包括嵌套的)会发生变异:
console.log(deepSanitize(req.query)) // { _id: {} }
console.log(req.query) // { _id: {} }
用 消除对象突变{...req.query}
:
console.log(deepSanitize({...req.query})) // { _id: {} }
console.log(req.query) // { _id: { '$ne': 1 } }
注意 我的回答不正确。请参考其他答案。
--
当客户端程序在 MongoDB 中组装查询时,它会构建 BSON 对象,而不是字符串。因此,传统的 SQL 注入攻击不是问题。
有关详细信息,请遵循文档
更新
避免eval
使用可以执行任意 JS 的表达式。如果您从用户那里获取输入并在eval
不清理输入的情况下运行类似的表达式,您可能会搞砸。正如 JoBu1324 所指出的where
,mapReduce
和之类的操作group
允许直接执行 JS 表达式。