MongoDB如何避免SQL注入混乱?

bul*_*ley 62 sql sql-injection mongodb

我正在阅读我信赖的O'Reilly书,并发现了一篇关于Mongo本质上是如何避免SQL注入式漏洞的消息.

在我的直觉中,我想我理解这一点.如果unsanitized瓦尔传递到查询,他们无法攻破了面向文档的查询结构的出UNION,JOIN,查询翻评论,等等.

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

bti*_*lly 42

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

任何涉及在解析的格式化文本中编码用户数据的任何API都有可能使调用者和被调用者不同意应该如何解析该文本.当数据被误解为元数据时,这些分歧可能是安全问题.无论您是在谈论printf格式字符串,包括HTML中的用户生成内容,还是生成SQL,都是如此.

由于MongoDB不解析结构化文本以确定要做什么,因此不可能将用户输入误解为指令,因此没有可能的安全漏洞.

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


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

但对于那些因自己代码中不明显的缺陷而遭受注入攻击的程序员而言,这种准确性是一种冷酷的安慰.我们很少有人区分外部工具和我们的代码与外部工具之间的所有层.而事实仍然是,我们需要保持警惕,以预测和关闭注射攻击.使用所有工具.在可预见的未来,情况仍将如此.

  • 请注意,这个答案(虽然有用)是不正确的 - 另外两个答案提供了一个"SQL注入式"攻击可以完成的情况.这是一个狂野的世界,您需要正确清理输入数据.;) (14认同)
  • @johndodo请注意,在发现PHP漏洞之前,我的答案出现了*.还请注意我的答案对于除PHP之外的每种语言都是正确的,并且漏洞的原因是PHP自愿以令人惊讶的方式解析数据. (5认同)
  • 很遗憾,这个答案的投票率如此之高。MongoDB No-SQL 攻击已经用多种语言进行了演示,这个答案给人一种错误的安全感。 (3认同)
  • 是的 - 我并不是故意反对你,但很多人通过谷歌找到了答案,所以我想我会把记录直接记录下来.此外,虽然我不熟悉其他Web语言,但是一些HTML输入将值作为数组发布,所以我会说这个问题不仅仅是PHP.一般规则仍然适用:始终验证用户输入. (2认同)
  • 这个问题还有更多内容.默认情况下,MongoDB允许执行任意JavaScript.从他们的文档:["你必须在这些情况下小心谨慎,以防止用户提交恶意JavaScript."](http://docs.mongodb.org/manual/faq/developers/#javascript).您可以禁用JS支持,但[也禁用JS支持服务器端脚本](http://docs.mongodb.org/manual/administration/security-checklist/).OWASP谈到这个[这里](https://www.owasp.org/index.php/Testing_for_NoSQL_injection) (2认同)

Per*_* P. 25

总结MongoDB 文档

BSON

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

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

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

  • 不是整个故事.在您的引用之下,相同的文档解释了如何对Mongo执行任意JavaScript.默认情况下会启用此行为,文档说:["在这些情况下,您必须小心谨慎,以防止用户提交恶意JavaScript."](http://docs.mongodb.org/manual/faq/developers/#javascript ).您可以禁用JS支持,但[也禁用JS支持服务器端脚本](http://docs.mongodb.org/manual/administration/security-checklist/).OWASP谈到这个[这里](https://www.owasp.org/index.php/Testing_for_NoSQL_injection) (4认同)

Ali*_*aka 6

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

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

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

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

collection.find(BasicDBObject.parse("{key: "input value"}"));
Run Code Online (Sandbox Code Playgroud)

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

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

collection.find(BasicDBObject.parse("{key: {$gt: ""}}"));
Run Code Online (Sandbox Code Playgroud)

在最后一个示例中,所有内容都被返回,即使我们的意思是只返回特定的记录。

直接使用过滤器时,请参阅此处有关 SQL 注入的更详尽说明。

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