使用 Mongoose 缓解 MongoDB 注入攻击
Mitigating MongoDB injection attacks with Mongoose
我正在为 NodeJS 使用 Mongoose ODM wrapper,我担心注入攻击。假设我有以下架构:
const UserSchema = new mongoose.Schema({ userName: String, password: String });
如果我执行如下所示的登录请求:
router.post('/login', (request, response) => {
const userName = request.body.userName;
const password = request.body.password;
User.findOne({ userName: userName }, function (error, user) {
// ... check password, other logic
});
});
我愿意使用以下 JSON 负载进行注入攻击,它总能找到用户:
{
"email": { "$gte": "" },
"password": { "$gte": "" }
}
我不关心密码,因为如果发现用户,密码会被散列,这会阻止任何实际登录,但我想确保我的输入经过清理,这样攻击者甚至无法做到这一点点.
我知道 mongo-sanitize NPM package referenced in a similar 似乎删除了所有以“$”开头的 JSON 键。我无论如何都打算使用它,但我永远不会允许用户提交原始的、未解析的 JSON。在这种情况下,假设我进行了正确的 null
检查,仅在 userName 上调用 toString() 是一种好习惯吗?
const userName = request.body.userName.toString();
这样可以避免执行查询,但感觉不太安全。我认为以下是更好的方法,因为它试图将 userName
转换为 String
:
User.findOne({ userName: { "$eq": userName } }, function (error, user) {
// ... other logic
});
我在 Model.findOne() documentation 中找不到与此相关的任何内容,这让我相信我忽略了一些东西。
如有任何见解,我们将不胜感激。
其他参考资料:
虽然您可以使用 $eq
来确保在查询中使用相等比较,但您的快速路由处理程序是执行请求格式验证的更好位置。
有效的 POST /login
请求正文中应包含 userName
和 password
字符串字段。如果不是,它甚至在到达 Mongoose 之前就应该被拒绝。
此外,您可以使用 npm 包“mongo-sanitize”,如下所示:
var sanitize = require('mongo-sanitize');
// The sanitize function will strip out any keys that start with '$' in the input,
// so you can pass it to MongoDB without worrying about malicious users overwriting
// query selectors.
var clean = sanitize(req.params.username);
Users.findOne({ name: clean }, function(err, doc) {
// ...
});
如果向 sanitize() 传递一个对象,它将改变原始对象。
我正在为 NodeJS 使用 Mongoose ODM wrapper,我担心注入攻击。假设我有以下架构:
const UserSchema = new mongoose.Schema({ userName: String, password: String });
如果我执行如下所示的登录请求:
router.post('/login', (request, response) => {
const userName = request.body.userName;
const password = request.body.password;
User.findOne({ userName: userName }, function (error, user) {
// ... check password, other logic
});
});
我愿意使用以下 JSON 负载进行注入攻击,它总能找到用户:
{
"email": { "$gte": "" },
"password": { "$gte": "" }
}
我不关心密码,因为如果发现用户,密码会被散列,这会阻止任何实际登录,但我想确保我的输入经过清理,这样攻击者甚至无法做到这一点点.
我知道 mongo-sanitize NPM package referenced in a similar null
检查,仅在 userName 上调用 toString() 是一种好习惯吗?
const userName = request.body.userName.toString();
这样可以避免执行查询,但感觉不太安全。我认为以下是更好的方法,因为它试图将 userName
转换为 String
:
User.findOne({ userName: { "$eq": userName } }, function (error, user) {
// ... other logic
});
我在 Model.findOne() documentation 中找不到与此相关的任何内容,这让我相信我忽略了一些东西。
如有任何见解,我们将不胜感激。
其他参考资料:
虽然您可以使用 $eq
来确保在查询中使用相等比较,但您的快速路由处理程序是执行请求格式验证的更好位置。
有效的 POST /login
请求正文中应包含 userName
和 password
字符串字段。如果不是,它甚至在到达 Mongoose 之前就应该被拒绝。
此外,您可以使用 npm 包“mongo-sanitize”,如下所示:
var sanitize = require('mongo-sanitize');
// The sanitize function will strip out any keys that start with '$' in the input,
// so you can pass it to MongoDB without worrying about malicious users overwriting
// query selectors.
var clean = sanitize(req.params.username);
Users.findOne({ name: clean }, function(err, doc) {
// ...
});
如果向 sanitize() 传递一个对象,它将改变原始对象。