2011-02-16 97 views
50

我正在閱讀我的可靠O'Reilly書,並且遇到了一段關於Mongo如何避免SQL注入式漏洞的泥沼。MongoDB如何避免SQL注入混亂?

在我的直覺中,我想我明白這一點。如果將unsanitized的變量傳遞到查詢中,它們不能通過UNION,JOIN,查詢變成註釋等來打破面向文檔的查詢結構。

MongoDB如何避免SQL注入混亂?這是查詢語法的性質嗎?

+0

我不認爲有人評論過使用解析中間件的潛在危險(比如``body-parser`與nodejs`express` lib,例如)。如果您將post參數解析爲JSON(這很常見),然後將這些參數(或這些參數的屬性)直接傳遞給mongo查詢,那麼攻擊者可以在您希望的字符串/數字處插入js對象(例如他們可以通過`{$ gt:-1}`並查看收藏中的所有文檔) – JoeRocc 2017-01-05 01:11:53

回答

39

MongoDB中通過不解析避免了潛在的問題。

在任何地方,任何涉及編碼用戶數據的格式化文本都會被解析的API有可能讓調用者和被調用者不同意如何解析文本。當數據被誤解爲元數據時,這些分歧可能是安全問題。無論您是在討論printf格式字符串(包括HTML中的用戶生成內容)還是生成SQL,都是如此。

由於MongoDB不解析結構化文本以找出要做什麼,因此不可能將用戶輸入誤解爲指令,因此不存在可能的安全漏洞。

順便提一下,避免需要解析的API的建議是http://cr.yp.to/qmail/guarantee.html中的第5項。如果您有興趣編寫安全軟件,其他6個建議也值得一看。

23

總結的MongoDB documentation

BSON

作爲客戶端程序組裝在MongoDB中的查詢時,它建立一個 BSON對象,而不是字符串。因此傳統的SQL注入攻擊不是問題。

但是,MongoDB並不免疫注入攻擊。正如在同一文檔中指出的那樣,由於MongoDB操作允許在服務器上直接執行任意的JavaScript表達式,注入攻擊仍然是可能的。文檔進入此詳細:

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

+4

不是整個故事。在你的引用下面,同樣的文檔解釋瞭如何針對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) – 2015-01-31 02:56:27

+0

毫無疑問,SQL注入攻擊不是問題,MongoDB不理解SQL。但是,MongoDB仍然可以使用非SQL注入攻擊。 – 2015-09-03 17:08:18

+0

這個問題特別提到了SQL注入攻擊的問題,但我同意應該明確與no-sql有關的風險。我已經更新了答案。 – 2015-09-03 17:26:11

3

爲了防止SQL注入,客戶端可以使用MongoDB的語言的API。這樣,所有的輸入都是簡單的值 - 命令不能被注入。一個Java例子:

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

的缺點是,你不能方便地測試你的過濾器。你不能將它複製到Mongo的shell並測試它。對於更大,更復雜的過濾器/查詢來說尤其成問題。

但是!!!還有一個API不使用過濾器的API - 可以解析任何json過濾器。 Java示例如下:

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

這很好,因爲您可以直接將過濾器複製到MongoDB外殼進行測試。

但是!!! (最後,但我承諾)這很容易NoSql注入。 Java示例,輸入值爲{$gt: ""}

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

在這最後一個示例中,即使我們只是爲了返回特定的記錄,也會返回所有內容。

請參閱here在直接使用過濾器時SQL注入的更全面的解釋。

最後一件事。我認爲有一種方法可以使用兩個原始過濾器,並且仍然可以防止SQL注入。例如,在Java中,我們可以使用Jongo's parameterized queries