[英]JavaScript NoSQL Injection prevention in MongoDB
如何防止 JavaScript NoSQL 注入 MongoDB?
我正在处理一个 Node.js 应用程序,我正在将req.body
传递到 mongoose 模型的保存 function 中,这是一个 json object。我认为幕后有保护措施,但事实并非如此。
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
}
注意我的答案不正确。 请参考其他答案。
-
客户端程序在MongoDB中组装查询时,将构建BSON对象而不是字符串。 因此,传统的SQL注入攻击不是问题。
有关详细信息,请遵循文档
更新
避免像eval
这样的表达式可以执行任意JS。 如果要从用户那里获取输入并运行类似eval
表达式而不清除输入,则可能会搞砸。 如JoBu1324所指出的,诸如where
, mapReduce
和group
允许直接执行JS表达式。
为了防止来自结构未知的数据对象的查询选择器注入
使用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)
清理对象(包括嵌套对象)是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 } }
如果您在 Mongoose 中使用Mongoose
Mongoose 6
他们引入了sanitizeFilter选项,可以按如下方式使用(来自他们的文档):
const obj = { username: 'val', pwd: { $ne: null } };
sanitizeFilter(obj);
obj; // { username: 'val', pwd: { $eq: { $ne: null } } });
通过将任何具有名称以 $ 开头的属性的嵌套对象包装在 $eq 中,来净化查询过滤器以防止查询选择器注入攻击。
您还可以将其设置为默认敏感:
mongoose.set('sanitizeFilter', true);
您还可以使用trusted()
跳过默认的敏感化:
const user = await User.findOne({
// Tell Mongoose to not sanitize `{ $ne: true }`
deleted: mongoose.trusted({ $ne: true }),
email: req.body.email,
hashedPassword: req.body.hashedPassword
}).setOptions({ sanitizeFilter: true });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.