Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB中的JavaScript NoSQL注入预防_Javascript_Node.js_Mongodb_Mongoose_Javascript Injection - Fatal编程技术网

MongoDB中的JavaScript NoSQL注入预防

MongoDB中的JavaScript NoSQL注入预防,javascript,node.js,mongodb,mongoose,javascript-injection,Javascript,Node.js,Mongodb,Mongoose,Javascript Injection,如何防止将JavaScript NoSQL注入MongoDB 我正在处理一个Node.js应用程序,我正在将一个json对象req.body传递到mongoose模型的save函数中。我原以为幕后有安全措施,但事实并非如此。注意 我的回答不正确。请参阅其他答案 -- 当客户端程序在MongoDB中组装查询时,它会构建一个BSON对象, 不是一串。因此,传统的SQL注入攻击不是问题 详情请参阅 更新 避免像eval这样可以执行任意JS的表达式。如果从用户处获取输入并运行类似于eval的表达式而不清

如何防止将JavaScript NoSQL注入MongoDB

我正在处理一个Node.js应用程序,我正在将一个json对象
req.body
传递到mongoose模型的save函数中。我原以为幕后有安全措施,但事实并非如此。

注意 我的回答不正确。请参阅其他答案

--

当客户端程序在MongoDB中组装查询时,它会构建一个BSON对象, 不是一串。因此,传统的SQL注入攻击不是问题

详情请参阅

更新


避免像
eval
这样可以执行任意JS的表达式。如果从用户处获取输入并运行类似于
eval
的表达式而不清理输入,则可能会出错。正如JoBu1324所指出的,像
where
mapReduce
group
这样的操作允许直接执行JS表达式。

虽然帖子已经过时了,但我正在回答

我知道三种方法

首先:有一个多用途。还通过过滤方式提供MongoDB注入保护

第二个:,帮助根据查询选择器注入清理mongodb查询

第三:我见过这个解决方案,它也可以应用于MongoDB。它的实现非常简单。仅使用JavaScript的内置
escape()
函数

escape()
将字符串转换为
ascii
code<代码>$ne转换为
%24ne

var privateKey = escape(req.params.privateKey);

App.findOne({ key: privateKey }, function (err, app) {
  //do something here
}
的答案不正确。您需要了解MongoDB中的NoSQL注入

示例(摘自)

如果
req.params.password
{$ne:1}
,将在不知道密码的情况下检索用户(
$ne
表示不等于1)

MongoDB驱动程序

您可以使用:

它将删除输入中以“$”开头的所有键,因此 可以将其传递给MongoDB,而无需担心恶意用户 覆盖

猫鼬驱动程序


由于它遵循一个模式,如果密码是一个字符串字段,它将把对象
{$ne:1}
转换为字符串,并且不会造成任何损坏。在这种情况下,您不需要进行清理,只需记住设置适当的模式。

以防止来自未知结构的数据对象的查询选择器注入

使用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)
sanitized对象(包括嵌套对象)进行变异:

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 } }

只要您使用
JSON.parse
(与
eval
相反)解析JSON并验证数据,就应该可以了。JSON本身并不危险:)不要阻止东西进入数据库,防止数据库中的东西作为代码运行。那么如何解析我的post对象呢?我的代码如下:module.exports.create=(post,cb)->post.created_at=Date.now()PostModel(post).save(err,post)->cb(err,post)post模型(JSON.parse(post)).save给出了一个错误-意外的标记我会在答案中添加一个“但是,小心JavaScript注入!”。考虑到中的node.js标记和javascript小节,这个答案是错误的吗?我正在自己寻找这个问题的答案。@JoBu1324我已经更新了答案。谢谢你改进了答案:)请不要破坏你的答案。@FINDarkside同意。我的回答不正确。更新。我刚刚用
req.params.password='{$ne:1}'
尝试了这个方法,但没有得到结果,您确定字符串
req.params.password
解析了它的json内容吗?@MohammadAli不,json不会自动解析。问题是当您收到一个对象
{$ne:1}
而不是字符串
{$ne:1}
时。我在我的博客上写了更多的细节:。答案中不应该提到这些吗?正如您所写的关于mongoose驱动程序的内容也适用于本机mongodb驱动程序。您还忽略了提到,对于给定的示例,类型需要是一个对象work@MohammadAli答案中已经提到了这一点。我说过
如果req.params.password是{$ne:1}
。JavaScript中的
{$ne:1}
表示对象而不是字符串。关于Mongoose,我说过它会将对象转换成字符串。最后强调:
在使用mongoose时,它会将对象{$ne:1}转换为字符串
,是否可以在.pre('save')函数中执行此操作?或者到那时已经太晚了?
console.log(deepSanitize(req.query))       // { _id: {} }
console.log(req.query)                     // { _id: {} }
console.log(deepSanitize({...req.query}))  // { _id: {} }
console.log(req.query)                     // { _id: { '$ne': 1 } }