私は信頼できるO'Reillyの本を読んでいて、MongoがSQLインジェクションのような欠陥の泥沼をどのように回避するかについての文章に出会いました。
私の腸では、私はこれを理解していると思います。サニタイズされていない変数がクエリに渡された場合、UNION
、JOIN
、クエリ変換コメントなどを使用してドキュメント指向のクエリ構造から抜け出すことはできません。
MongoDBはSQLインジェクションの混乱をどのように回避しますか?このクエリ構文の性質だけですか?
MongoDBは、解析しないことで問題の可能性を回避します。
解析されるフォーマットされたテキストでユーザーデータをエンコードすることを含む任意のAPIは、呼び出し元と呼び出し先がそのテキストの解析方法に同意しない可能性があります。データがメタデータとして誤って解釈される場合、これらの不一致はセキュリティの問題になる可能性があります。これは、ユーザーがHTMLで生成したコンテンツを含むprintf形式の文字列であれ、SQLの生成であれ、当てはまります。
MongoDBは構造化されたテキストを解析して何をすべきかを判断しないため、ユーザー入力を指示として誤って解釈する可能性はなく、したがってセキュリティホールも発生しません。
ちなみに、解析を必要とするAPIを避けるためのアドバイスは、 http://cr.yp.to/qmail/guarantee.html の項目5です。安全なソフトウェアの作成に興味がある場合は、他の6つの提案も検討する価値があります。
更新(2018):私が与えた最初の答えは、私の知る限り真実のままです。 MongoDBに送信されるものから返されるものまで、SQLインジェクション攻撃はありません。私が知っているインジェクション攻撃はMongoDBの外部で発生し、外部言語とライブラリがMongoDBに渡されるデータ構造をどのように設定するかという問題です。さらに、この脆弱性の場所は、データ構造になるまでのデータの解析方法にあります。したがって、元の答えは、インジェクション攻撃を回避する方法と、攻撃の危険にさらされるものの両方を正確に説明しています。
しかし、この精度は、自分のコードでは明らかではなかった欠陥からのインジェクション攻撃に見舞われるプログラマーにとっては冷静です。外部ツールと、コードとその外部ツールの間のすべてのレイヤーを区別する人はほとんどいません。そして、インジェクション攻撃を予測して終了するためには、私たち側の警戒が必要であるという事実が残っています。すべてのツールで。そして、これは近い将来に当てはまります。
MongoDBを要約するには ドキュメント
[〜#〜] bson [〜#〜]
クライアントプログラムはMongoDBでクエリを組み立てるときに、文字列ではなくBSONオブジェクトを構築します。したがって、従来のSQLインジェクション攻撃は問題になりません。
ただし、MongoDBはインジェクション攻撃から免れません。同じドキュメントに記載されているように、MongoDB操作では任意のJavaScript式をサーバー上で直接実行できるため、インジェクション攻撃は依然として可能です。ドキュメントの詳細は次のとおりです。
PHP mongoDBは、No-SQLインジェクションに対して脆弱になる可能性があります。
http://www.idontplaydarts.com/2010/07/mongodb-is-vulnerable-to-sql-injection-in-php-at-least/
SQLインジェクションから保護するために、クライアントはMongoDBの言語APIを使用できます。このように、すべての入力は単純な値です-コマンドを注入することはできません。 A Java例:
collection.find(Filters.eq("key", "input value"))
欠点は、フィルターを簡単にテストできないことです。 Mongoのシェルにコピーしてテストすることはできません。より大きく、より複雑なフィルター/クエリでは特に問題があります。
しかし!!!フィルターの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のパラメーター化されたクエリ 。を使用できます
データベースはコンテンツを解析しない可能性がありますが、脆弱なコードの他の領域があります。