MongoDB如何避免SQL注入混乱?


71

我读了我值得信赖的O'Reilly书,发现一段关于Mongo本质上如何避免SQL注入式缺陷的麻烦的文章。

以我的直觉,我想我明白这一点。如果unsanitized瓦尔传递到查询,他们无法攻破了面向文档的查询结构的出UNIONJOIN,查询翻评论,等等。

MongoDB如何避免SQL注入混乱?只是这种查询语法的本质吗?


我认为没有人对使用解析中间件的潜在危险发表评论(例如body-parser,使用nodejs expresslib)。如果您将发布参数解析为JSON(这是很常见的),然后将这些参数(或这些参数的属性)直接传递到mongo查询中,则攻击者可以在您希望有字符串/数字的js对象中插入(例如他们可以通过{$gt:-1}并查看您收藏中的所有文档)

Answers:


44

MongoDB通过不解析避免了潜在的问题。

任何涉及将用户数据编码为已解析格式文本的API,无论在任何地方,都可能使调用方和被调用方在如何解析该文本上存在分歧。当数据被误解为元数据时,这些分歧可能是安全问题。无论您是在谈论printf格式字符串,包括用户生成的HTML内容还是生成SQL,都是如此。

由于MongoDB不会解析结构化文本来确定要做什么,因此不可能将用户输入误解为指令,因此不会存在安全漏洞。

顺便提一下,避免需要解析的API的建议是http://cr.yp.to/qmail/guarantee.html中的第5项。如果您对编写安全软件感兴趣,那么其他6条建议也值得一看。


更新(2018):就我所知,我给出的原始答案仍然正确。从发送到MongoDB的内容到发送回的内容,没有SQL注入攻击。我知道的注入攻击发生在MongoDB之外,实际上是外部语言和库如何设置将传递给MongoDB的数据结构方面的问题。此外,漏洞的位置在于如何在成为数据结构的过程中解析数据。因此,原始答案准确地描述了如何避免注入攻击,以及使您面临注入风险的原因。

但是,对于那些因自己的代码中不明显的缺陷而遭受注入攻击的程序员而言,这种准确性实在令人不寒而栗。我们很少有人区分外部工具以及代码与外部工具之间的所有层。而且事实仍然是,我们需要提高警惕,才能预测和结束注入攻击。使用所有工具。在可预见的将来,情况仍将如此。


14
请注意,此答案(尽管有帮助)是错误的-其他两个答案提供了可以进行“类似SQL注入”攻击的情况。那里是一个狂野的世界,您需要正确清理输入数据。;)
johndodo

5
@johndodo请注意,我的答案出现发现PHP漏洞之前。还请注意,我的答案对于除PHP之外的所有其他语言仍然正确,并且造成这种漏洞的原因是PHP自愿以令人惊讶的方式解析数据。
btilly 2011年

2
是的-我并不是要反对你,但是很多人都通过Google找到了答案,所以我想我会打破纪录的。另外,虽然我不太熟悉其他网络语言,但是一些HTML输入将值作为数组发布,因此我认为问题不仅仅在于PHP。通用规则仍然适用:始终验证用户输入。
johndodo 2011年

2
这个问题还有更多。默认情况下,MongoDB允许执行任意JavaScript。根据他们的文档:“在这种情况下,您必须格外小心,以防止用户提交恶意JavaScript。” 。您可以禁用JS支持,但这也将禁用JS对服务器端脚本的支持。OWASP在这里
Hawkeye Parker'1

3
如此之高的答案令人遗憾。MongoDB No-SQL攻击已经以多种语言进行了演示,并且这种回答给人一种错误的安全感。
David H. Bennett

29

总结MongoDB文档

BSON

客户端程序在MongoDB中组装查询时,将构建BSON对象而不是字符串。因此,传统的SQL注入攻击不是问题。

但是,MongoDB无法免受注入攻击。如同一文档中所述,由于MongoDB操作允许任意JavaScript表达式直接在服务器上执行,因此注入攻击仍然可能。该文档对此进行了详细介绍:

http://docs.mongodb.org/manual/faq/developers/#javascript


4
并非全部。在您的报价下方,同一文档说明了如何针对Mongo执行任意JavaScript。默认情况下,此行为是启用的,文档中说:“在这种情况下,您必须格外小心,以防止用户提交恶意JavaScript。” 。您可以禁用JS支持,但这也将禁用JS对服务器端脚本的支持。OWASP在这里
Hawkeye Parker

不用说,SQL注入攻击不是问题,MongoDB不了解SQL。但是,MongoDB仍然可能会发生No-SQL注入攻击。
David H. Bennett

这个问题专门询问有关SQL注入攻击的问题,但我同意应该明确与no-sql相关的风险。我已经更新了答案。
Pero P.

18

1
我刚刚看到了。请注意,从根本上讲,PHP可以有效地解析用户输入,从而允许用户以一种不可能的方式混淆数据和元数据。
btilly 2011年

@James因此在变量之前放置一个字符串强制转换将解决此问题...还有其他我需要担心的问题,还是唯一的解决方法?
阿卜杜勒

6

为了防止SQL注入,客户端可以使用MongoDB的语言API。这样,所有输入都是简单值-无法注入命令。一个Java示例:

collection.find(Filters.eq("key", "input value"))

缺点是您无法轻松测试过滤器。您无法将其复制到Mongo的外壳并对其进行测试。对于更大,更复杂的过滤器/查询尤其有问题。

但!!!还有一个API不使用过滤器的API-可以解析任何json过滤器。下面的Java示例:

collection.find(BasicDBObject.parse("{key: "input value"}"));

很好,因为您可以将过滤器直接复制到MongoDB Shell进行测试。

但!!!(最后,但我保证)这很容易发生NoSql注入。Java示例,其中输入值为{$gt: ""}

collection.find(BasicDBObject.parse("{key: {$gt: ""}}"));

在最后一个示例中,即使我们仅意味着要返回特定记录,也将返回所有内容。

这里直接使用过滤器时,有关SQL注入的更详尽说明。

最后一件事。我认为有一种方法既可以使用原始过滤器,又可以防止SQL注入。例如,在Java中,我们可以使用Jongo的参数化查询


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.