防止NoSQL注入:猫鼬不应该根据给定的模式转换输入吗?



希望使用mongoDB防止NOSQL注入攻击。

var mongoose = require('mongoose'); // "^5.5.9"
var Schema = mongoose.Schema;
var historySchema = new Schema({
  userId: {
    type: String,
    index: true,
  },
  message: {},
  date: {
    type: Date,
    default: Date.now,
  }
});
var history = mongoose.model('history', historySchema);
// the following is to illustrate the logic, not actual code
function getHistory(user){
  history.find({userId: user}, function(err, docs) {
    console.log(docs)
  }
}

基于对类似问题的答案,我的理解是,使用杂种并将字段定义为字符串应防止查询注入。但是,通过将user输入更改为查询对象,可以返回所有用户。例如:

getHistory({$ne: 1}) // returns the history for all users

我知道在到达猫鼬查询之前(例如使用Mongo-Sanitizize(之前,请先防止这种攻击。但是我想知道我定义模式的方式是否有问题,还是不能指望猫鼬根据模式转换输入。

预先感谢!

这部分足够好,您在那里不需要其他任何东西。有接收字符串并使用字符串的方法。

最好的方法是在处理任何内容之前先验证可以修改的输入(通常是http请求((我可以推荐https://github.com/hapijs/joi易于使用,您可以检查是否是否所有必需的字段,如果所有字段均以正确的格式(。

因此,在击中控制器之前,将验证验证到中间件中。或在控制器的开头。

从那时起,您可以完全控制所有代码,并且您相信您通过验证获得的内容,因此某人通过对象而不是字符串并通过。

遵循"瘦控制器,脂肪模型"范式之后,最好从模型中揭示自定义验证模式,以便在您的控制器中用于发布并提出请求。这意味着任何尝试输入您数据库的数据首先都针对验证模式进行消毒。每个杂种模型都应拥有自己的验证模式。

我个人最喜欢的是Joi。这相对简单有效。这是文档的链接:https://www.npmjs.com/package/@hapi/joi

JOI模式允许类型检查(即布尔值与字符串与编号等(,如果您的文档具有所需字段,则强制输入,以及其他特定于类型的执行,例如数字,枚举值,枚举值,枚举值,等

这是您在模型中包含的示例:

const Joi = require('joi');
...
function validateHistory(history) {
  const historySchema = {
    userId: Joi.string(),
    message: Joi.object(),
    date: Joi.date()
  }
   return Joi.validate(history, historySchema);
}
...
module.exports.validate = validateHistory;

然后在您的控制器中您可以做:

const {
validate
} = require('../models/history');
...
router.post('/history', async (req, res) => {
    const {
      error
    } = validate(req.body.data);
    if (error) return res.status(400).send(error.details[0].message);

  let history = new History({
      userID: req.body.user,
      message: req.body.message,
      date: req.body.date
    })
    history = await history.save();
    res.send(history);
});

*请注意,在真正的应用程序中,此路线在处理请求之前还将具有身份验证回调。

最新更新