提问人:Bugwhacker 提问时间:8/22/2021 更新时间:8/25/2023 访问量:2443
你能告诉我express-mongo-sanitize是否有效吗?
Can you tell me if express-mongo-sanitize is working?
问:
我正在尝试为我不起眼的小型 MERN Web 应用程序设置一些安全中间件,我目前正在使用 helmet 和 express-mongo-sanitize,专门用于防止 NoSQL 注入攻击。
但是,我已经在我的服务器.js文件中进行了如下设置:
const express = require('express')
const helmet = require('helmet')
const mongoSanitize = require('express-mongo-sanitize')
...
app.use(mongoSanitize())
app.use(helmet())
// Routes below
...
我试图通过进行模拟注册来测试它,例如:
用户名: {“$gt”: “”} password: 'TestPassword'
因此,req.body 将是:
{
username: '{"$gt": ""}',
password: 'TestPassword'
}
但是 express-mongo-sanitize 似乎没有捕捉到它,它会进入我的数据库。我是不是误会了什么?用户名键的值是一个字符串,所以也许它已经可以了?请原谅我的无知,我正在学习。
答:
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": "" }
}
据我了解,从调试和浏览代码来看,它清理的键是具有 $ 或点的查询和 post 参数的 key=value 对中的任何潜在键。它还会尝试清理请求正文和标头中的任何键。
例如,即使是上面上一个用户提供的 json 也无法做到这一点。
但 https://your-domain/?$user=json 将被清理为 user=json。
它不会像您和我所期望的那样从参数的值中删除 $。我还在 github 上向创建者提出了一个问题,看看他怎么说。我认为安全风险是针对密钥和值的。如果您不保存 mongodb 的密钥而是保存值,这没有任何好处。
作为参考,它会检查以下 HTTP 部分以删除任何可能有害的 $ 或 .
['body', 'params', 'headers', 'query'].forEach(function (key) ...
我认为@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);
遇到了同样的问题,对我有用的是在使用包之前解析传入的请求正文。喜欢这个。。。mongoSanitize
const express = require("express")
const mongoSanitize = require("express-mongo-sanitize')
const app = express()
app.use(express.json())
app.use(mongoSanitize())
仔细阅读文档
此模块在以 $ 符号开头的对象中搜索任何键 或包含 .、来自 req.body、req.query 或 req.params。然后它可以 也:
- 从对象中完全删除这些键和关联数据,或者
- 将禁止的字符替换为另一个允许的字符。
它搜索 KEYS 而不是值。所以在这种情况下
{ username: '{"$gt": ""}', password: 'TestPassword'}
$ 符号存在于 key 的值中,而不是 key 本身。这就是为什么 express-mongo-sanitize 没有捕获它的原因。username
为了更好地理解它,请看这个例子
// 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",
}
评论