$where
MongoDB 中的运算符是一个最好避免的特性。它的性能很糟糕,不仅仅是因为它没有从索引中受益。几乎所有常见的用例都可以通过常见的查找查询或聚合更有效地解决,尤其是像这样微不足道的用例。但这是安全堆栈交换,而不是堆栈溢出,所以让我们关注安全影响。
该$where
语句将 javascript 代码片段传递给数据库,然后数据库将对集合中的每个文档执行一次。值得庆幸的是,该脚本无法访问db
对象和其他危险的 shell 函数,并且它适用于文档的副本,因此攻击者至少不能像许多 SQL 注入那样更改数据库内容。但它例如容易受到攻击者想要返回其他结果而不是预期的攻击。
让我们举个例子。假设我们有一个博客。我们的博客有很多可以公开阅读的文章,但我们也有一些私人文章供我们内部使用,不应该发布。因此hidden
,我们的文档中有一个字段,它可以是true
或false
取决于我们的访问者是否应该看到该文章。我们的 MongoDB 查询用于获取特定类别中所有文章的列表以将其显示给网站访问者,如下所示:
db.articles.find({"$where": "this.hidden == false && this.category == '"+category+"'" });
这应该确保没有人看到我们隐藏的文章。或者是吗?当用户控制category
-variable 时,他们可以将其设置为以下字符串:
'; return '' == '
发送到数据库的结果 Javascript 片段是这样的:
this.hidden == false && this.category == ''; return '' == ''
当您有一个包含多个以 分隔的命令的 javascript 片段时;
,它们将作为函数执行,并且需要一条return
语句来确定将哪个值传递回调用者。此函数将始终返回 true。这意味着用户还将看到我们收藏中的所有文章,包括那些应该被隐藏的文章。