为了立即启动和运行某些东西,我将 Express 查询字符串对象直接传递给 mongoose 查找函数。我很好奇的是,这种做法在实时应用程序中会有多危险。我知道 RDBMS 极易受到 SQL 注入的攻击。除了“清理你的输入”的好建议之外,这段代码有多邪恶:
app.get('/query', function (req, res) {
models.findDocs(req.query, function (err, docs) {
res.send(docs);
});
});
意味着对
http://localhost:8080/query?name=ahsteele&status=a
的获取请求只会将以下内容推送到 findDocs 函数中:
{
name: 'ahsteele',
status: 'a'
}
出于很多原因,这感觉很恶心,但它有多不安全?将查询参数传递给 mongodb 的最佳做法是什么?快递是否提供任何开箱即用的消毒服务?
就注入问题而言,就像使用 SQL 一样,风险要低得多……尽管理论上可以通过未知的攻击向量实现。
数据结构和协议是二进制和 API 驱动的,而不是利用特定领域语言中的转义值。基本上,你不能只是欺骗解析器在最后添加一个
;db.dropCollection()
。
如果它只用于查询,它可能没问题......但我仍然提醒你使用一点点验证:
$
开头的参数名称,如$where
等另外,请记住,空查询会返回所有内容。您可能希望限制该返回值。 :)
运算符注入在这里是一个严重的问题,我建议您至少编码/转义某些字符,更具体地说是
$
符号:http://docs.mongodb.org/manual/faq/developers/#dollar-sign -运算符逃逸
如果允许用户将
$
符号附加到您的 $_GET
或 $_POST
中的字符串或元素的开头,或者他们将快速使用它的任何内容:http://xkcd.com/327/至少可以说,你会成为一个赢家。
据我所知,Express 不提供任何开箱即用的消毒控制。您可以编写自己的中间件,或者根据自己的逻辑进行一些基本检查。正如您所说,您提到的情况有点冒险。
但是为了便于使用,Mongoose 模型中内置的所需类型至少为您提供了默认的清理和一些控制进入或不进入的内容。
例如像这样的东西
var Person = new Schema({
title : { type: String, required: true }
, age : { type: Number, min: 5, max: 20 }
, meta : {
likes : [String]
, birth : { type: Date, default: Date.now }
}
});
还检查此以获取更多信息。