MongoDB 如何避免 SQL 注入混乱?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5021456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does MongoDB avoid the SQL injection mess?
提问by buley
I was reading my trusty O'Reilly book and came across a passage about how Mongo, by nature, avoids the morass of SQL injection-like flaws.
我正在阅读我值得信赖的 O'Reilly 书,并偶然发现了一段关于 Mongo 如何在本质上避免类似 SQL 注入缺陷的泥潭。
In my gut, I think I understand this. If unsanitized vars are passed into queries, they can't break out of the document-oriented query structure with a UNION
, JOIN
, query turned comment, etc.
在我的直觉中,我想我明白这一点。如果未净化的变量被传递到查询中,它们就不能用UNION
, JOIN
, 查询变成注释等打破面向文档的查询结构。
How does MongoDB avoid the SQL injection mess? Is it just by nature of this query syntax?
MongoDB 如何避免 SQL 注入混乱?仅仅是这种查询语法的性质吗?
采纳答案by btilly
MongoDB avoids the potential for problems by not parsing.
MongoDB 通过不解析来避免出现问题的可能性。
Any API, anywhere, that involves encoding user data in formatted text that gets parsed has the potential for the caller and callee to disagree on how that text should be parsed. These disagreements can be security issues when data is misinterpreted as metadata. This is true whether you're talking about printf format strings, including user generated content in HTML, or generating SQL.
任何涉及将用户数据编码为经过解析的格式化文本的 API 都有可能导致调用方和被调用方在如何解析文本上存在分歧。当数据被误解为元数据时,这些分歧可能是安全问题。无论您是在谈论 printf 格式字符串,包括用户生成的 HTML 内容,还是生成 SQL,都是如此。
Since MongoDB doesn't parse structured text to figure out what to do, there is no possibility of misinterpreting user input as instructions, and hence no possible security hole.
由于 MongoDB 不会解析结构化文本来确定要做什么,因此不可能将用户输入误解为指令,因此也不可能存在安全漏洞。
Incidentally the advice of avoiding APIs that require parsing is item 5 in http://cr.yp.to/qmail/guarantee.html. If you're interested in writing secure software, the other 6 suggestions are worth looking at as well.
顺便提一下,避免使用需要解析的 API 的建议是http://cr.yp.to/qmail/guarantee.html 中的第5 项。如果您对编写安全软件感兴趣,那么其他 6 条建议也值得一看。
Update (2018): The original answer as I gave it remains true to the best of my knowledge. From the point of what is sent to MongoDB to what is sent back, there is no SQL injection attack. The injection attacks that I'm aware of happen outside of MongoDB and are actually problems in how external languages and libraries set up the data structure that will be passed to MongoDB. Furthermore the location of the vulnerability is in how data is parsed on the way to becoming a data structure. Therefore the original answer accurately describes both how to avoid injection attacks, and what puts you at risk of them.
更新(2018 年):据我所知,我给出的原始答案仍然是真实的。从发送到 MongoDB 的内容到返回的内容,没有 SQL 注入攻击。我所知道的注入攻击发生在 MongoDB 之外,实际上是外部语言和库如何设置将传递给 MongoDB 的数据结构的问题。此外,漏洞的位置在于在成为数据结构的过程中如何解析数据。因此,原始答案准确地描述了如何避免注入攻击,以及是什么让您面临注入攻击的风险。
But this accuracy is cold comfort to a programmer who is hit by injection attacks from defects that were not obvious in their own code. Few of us distinguish between the external tool and all the layers between our code and that external tool. And the fact remains that it requires vigilance on our part to anticipate and close off injection attacks. With all tools. And this will remain the case for the foreseeable future.
但是这种准确性对于那些受到来自他们自己的代码中并不明显的缺陷的注入攻击的程序员来说是一种冷酷的安慰。我们中很少有人区分外部工具和我们的代码和外部工具之间的所有层。事实仍然是,我们需要保持警惕,以预测和关闭注入攻击。使用所有工具。在可预见的未来,情况仍将如此。
回答by Pero P.
To summarize the MongoDB documentation
总结 MongoDB文档
BSON
As a client program assembles a query in MongoDB, it builds a BSON object, not a string. Thus traditional SQL injection attacks are not a problem.
BSON
当客户端程序在 MongoDB 中组装查询时,它会构建一个 BSON 对象,而不是一个字符串。因此,传统的 SQL 注入攻击不是问题。
However, MongoDB is not immune from injection attacks. As noted in the same documentation, injection attacks are still possible as MongoDB operations allow arbitrary JavaScript expressions to be executed directly on the server. The documentation goes into this in detail:
然而,MongoDB 并不能免于注入攻击。正如同一文档中所指出的,注入攻击仍然是可能的,因为 MongoDB 操作允许直接在服务器上执行任意 JavaScript 表达式。文档详细介绍了这一点:
回答by James
With PHP mongoDB can become vulnerable to No-SQL injection:
使用 PHP mongoDB 可能容易受到 No-SQL 注入的攻击:
http://www.idontplaydarts.com/2010/07/mongodb-is-vulnerable-to-sql-injection-in-php-at-least/
http://www.idontplaydarts.com/2010/07/mongodb-is-vulnerable-to-sql-injection-in-php-at-least/
回答by AlikElzin-kilaka
To protect against SQL injection, clients can use MongoDB's language APIs. This way, all the input is simple value - commands cannot be injected. A Java example:
为了防止 SQL 注入,客户端可以使用 MongoDB 的语言 API。这样,所有输入都是简单的值 - 无法注入命令。一个Java示例:
collection.find(Filters.eq("key", "input value"))
collection.find(Filters.eq("key", "input value"))
The drawback is that you cannot easily test your filter. You cannot copy it to Mongo's shell and test it. Especially problematic with bigger, more complex filters/queries.
缺点是您无法轻松测试过滤器。您无法将其复制到 Mongo 的 shell 并对其进行测试。对于更大、更复杂的过滤器/查询尤其成问题。
BUT!!! there's also an API to not use the filter's API - enabling to parse any json filter. Java example below:
但!!!还有一个不使用过滤器 API 的 API - 能够解析任何 json 过滤器。下面的Java示例:
collection.find(BasicDBObject.parse("{key: "input value"}"));
This is nice because you can copy the filter directly to the MongoDB shell to test it out.
这很好,因为您可以将过滤器直接复制到 MongoDB shell 以对其进行测试。
BUT!!! (last but, I promise) this is prone to NoSql injection. Java example, where the input value is {$gt: ""}
.
但!!!(最后但是,我保证)这很容易被 NoSql 注入。Java 示例,其中输入值为{$gt: ""}
.
collection.find(BasicDBObject.parse("{key: {$gt: ""}}"));
In this last example, everything is returned, even though we meant only for the specific records to return.
在最后一个示例中,所有内容都被返回,即使我们的意思是只返回特定的记录。
See herea more thorough explanation on SQL injection when using the filters directly.
直接使用过滤器时,请参阅此处对 SQL 注入的更详尽解释。
One last thing. I think there's a way to use both raw filters and still protect against SQL injection. For example, in Java, we can use Jongo's parameterized queries.
最后一件事。我认为有一种方法既可以使用原始过滤器,又可以防止 SQL 注入。例如,在 Java 中,我们可以使用Jongo 的参数化查询。
回答by Brian Blain
The database might not parse the content but there are other areas of the code that are vulnerable.
数据库可能不会解析内容,但代码的其他区域很容易受到攻击。