24

如何防止 JavaScript NoSQL 注入 MongoDB?

我正在开发一个 Node.js 应用程序,我正在将req.bodyjson 对象传递给猫鼬模型的保存函数。我以为幕后有保障措施,但事实并非如此。

4

4 回答 4

37

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 }为字符串,并且不会造成任何损坏。在这种情况下,您不需要清理,只需记住设置适当的架构。

于 2016-07-16T21:49:45.463 回答
13

尽管帖子已过时,但我正在回答。

我知道三种方法。

第一:有一个多用途的内容过滤器。还通过过滤方式提供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
}
于 2015-08-08T21:50:10.983 回答
3

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

使用 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 } }
于 2019-10-22T19:33:30.230 回答
-2

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

--

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

有关详细信息,请遵循文档

更新

避免eval使用可以执行任意 JS 的表达式。如果您从用户那里获取输入并在eval不清理输入的情况下运行类似的表达式,您可能会搞砸。正如 JoBu1324 所指出的wheremapReduce和之类的操作group允许直接执行 JS 表达式。

于 2012-11-18T09:02:43.123 回答