你能告诉我express-mongo-sanitize是否有效吗?

问题描述 投票:0回答:5

我正在尝试为我不起眼的小型 MERN Web 应用程序设置一些安全中间件,我目前正在使用头盔和express-mongo-sanitize,专门用于防止 NoSQL 注入攻击。

但是,我已经在我的 server.js 文件中进行了如下设置:

const express = require('express')
const helmet = require('helmet')
const mongoSanitize = require('express-mongo-sanitize')

...

app.use(mongoSanitize())
app.use(helmet())

// Routes below

...

我尝试通过模拟注册来测试它,例如:

用户名: {"$gt": ""} 密码:'测试密码'

这样 req.body 将是:

{

username: '{"$gt": ""}',

password: 'TestPassword'

}

但express-mongo-sanitize似乎没有捕获它,它会进入我的数据库。我误解了什么吗?用户名键的值是一个字符串,所以也许已经可以了?请原谅我的无知,我正在学习。

javascript mongodb security sql-injection mern
5个回答
2
投票

express-mongo-sanitize 的作用是清理以美元符号开头的键。

username: '{"$gt": ""}' --> this isn't a key starting with a dollar sign. Rather, the value of username is just a string.

尝试向其发送此对象:

{

"username": { "$gt": "" }

}

1
投票

根据我的理解,从调试和浏览代码来看,它清理的键是查询和发布参数的键=值对中具有 $ 或点的任何潜在键。它还尝试清理请求正文和标头中的所有键。

例如,即使是上面之前用户提供的json也不会这样做。

但是 https://your-domain/?$user=json 将被清理为 user=json。

它不会像你和我所期望的那样从参数值中删除 $ 。我还在 github 上向创建者提出了一个问题,看看他怎么说。我认为安全风险是针对密钥和价值的。如果您不将密钥保存到 mongodb 而是保存值,则这没有任何好处。

作为参考,它会检查以下 HTTP 部分以删除任何潜在有害的 $ 或 .

['body', 'params', 'headers', 'query'].forEach(function (key) ...


1
投票

遇到了同样的问题,对我有用的是在使用

mongoSanitize
包之前解析传入的请求正文。像这样...

const express = require("express")
const mongoSanitize = require("express-mongo-sanitize')

const app = express()

app.use(express.json())
app.use(mongoSanitize())


0
投票

我认为@A10n 的答案是正确的,因此看来“express-mongo-sanitize”只是部分解决方案。我添加了快速而肮脏的解决方案,从每个 req.body/params 对象中删除大括号(这应该会削弱大多数 NoSQL 攻击),如下所示:

// Middleware that replaces all {} symbols with [] to prevent NoSQL attack
    const removeCurlies = (req, res, next) => {
      Object.keys(req.body).forEach((key) => {
        req.body[key] = _.replace(req.body[key], "{", "[");
        req.body[key] = _.replace(req.body[key], "}", "]");
      });
      Object.keys(req.params).forEach((key) => {
        req.params[key] = _.replace(req.params[key], "{", "[");
        req.params[key] = _.replace(req.params[key], "}", "]");
      });
      next();
    };

然后,在您的路线之前:

    app.use(removeCurlies);

0
投票

仔细阅读文档

此模块搜索以 $ 符号开头的对象中的任何 keys 或者包含来自 req.body、req.query 或 req.params 的 .。那么就可以 要么:

  • 从对象中完全删除这些键和关联数据,或者
  • 将禁止的字符替换为另一个允许的字符。

它搜索 KEYS,而不是值。所以在这种情况下

{ username: '{"$gt": ""}', password: 'TestPassword'}

$ 符号存在于 username 键的

value
中,而不是键本身。这就是为什么 express-mongo-sanitize 无法捕获它。

为了更好地理解它,请看这个例子

// req.body
{ 
    "username": "{'$gt': ''}", 
    "password": "TestPassword",
    "$ne": "1",
    "$gt": "",
}

// the default implementation of express-mongo-sanitize will remove 
// the last two keys and not the first one.
// So, right after the middleware you will get this 
{ 
    username: "{'$gt': ''}", 
    password: "TestPassword",
}
© www.soinside.com 2019 - 2024. All rights reserved.