Introduction
攻撃者は、MongoDBなどSQL問合せ言語を用いないデータベースの脆弱性を突いて、クエリにコードを注入する可能性があります。この記事では、NoSQLインジェクションと従来のSQLインジェクションの違いや回避方法について解説します。また、NoSQLインジェクション攻撃の概要、具体例、ブラインドインジェクション、ペイロードについても紹介します。
NoSQLデータベースは、SQL問合せ言語を用いない非リレーショナルなデータベースです。代表例として、MongoDB、Cassandra DB、CouchDB、Riakなどがあり、特にMongoDBが有名です。
SQLインジェクションとNoSQLインジェクションの違いは、NoSQLデータベースが用途に応じた様々なデータモデルを採用している点にあります。SQLデータベースはテーブルにデータを保存するのに対し、NoSQLはドキュメント、キー・バリュー、グラフ、カラムファミリーなど多様な形式でデータを扱います。動的なスキーマ定義により、新たなフィールドやデータの追加・変更が容易です。
NoSQLインジェクションとは、NoSQLデータベースを利用するウェブアプリに生じたミスを指します。この脆弱性を利用すると、悪意ある者が認証を回避し、データの読み出しや改ざん、果てはアプリの完全な制御を奪う恐れがあります。こうした攻撃は、入力データの検証不足によって引き起こされます。
攻撃者は、ログイン認証を回避するために、各フィールドにMongoDBの演算子、例えば $eq(と等しい)、$ne(と等しくない)、または $gt(より大きい)などを入力して試みる場合があります。以下は、PHPアプリでフォームから直接入力値を利用してクエリを組み立てる危険な方法です:
$question = array("user" => $_POST["username"], "secret word" =>
$_POST["password"]);
PHPの標準的なエスケープ処理によりログイン認証を確認していた場合、攻撃者は正常に見えるMongoDBクエリを注入し、検証を回避できることがあります。次のPOSTリクエストを送信するだけで実行される可能性があります:
username[$ne]=1& password[$ne]=1
PHPはこれを次のような配列に変換します:
array("username" => array("$ne" => 1), "secret key" =>
array("$ne" => 1));
これにより、ユーザ名とパスワードが1と等しくない全てのユーザが返され、攻撃者は検証を回避してMongoDBに送信する恐れがあります。
JavaScriptによるNoSQLインジェクションの例では、検証されずに入力値をMongoDBの$where演算子に渡す脆弱なアプリが問題となります。攻撃者はこの弱点を利用して、制限された機能のJavaScriptコードを注入できます。直接任意のJavaScriptを実行できなくても、十分な被害を与える可能性があります。
通常、MongoDBでは$where演算子付きのfind()関数を使ってコレクションを検索します。例えば:
db.collection.find( { $where: function() {
return (this.name == 'Invicti') } } );
「Invicti」という名前のレコードが取得されます。脆弱なPHPアプリでは、$userData変数など、検証されていないクライアント入力が直接クエリに埋め込まれる可能性があります:
db.collection.find( { $where: function() {
return (this.name == $userData) } } );
注入が成功すると、攻撃者は例えば「'a'; sleep(5000)」のような文字列を$userDataに注入し、サーバを5秒間停止させる恐れがあります。サーバは以下のクエリを実行します:
db.collection.find( { $where: function() {
return (this.name == 'a'; sleep(5000) ) } } );
これは、クエリがアプリ内の言語で書かれているために可能な注入の一例に過ぎません。例えば、サーバサイドでNode.jsを利用している場合、Node.jsへのJavaScriptインジェクションも考えられ、これはMongoDB、ExpressJS、AngularJS、Node.jsからなるMEANスタックでよく見られるケースです。
これらのデータベースは新しい技術であり、SQLやリレーショナルデータベースに慣れた開発者にとっては、不適切なコード記述のリスクが高まります。NoSQLデータベースのセキュリティルールやガイドラインは、十分に注意して確認すべきです。
SQLインジェクションと同様、クエリ作成時には検証されていない入力値の使用を避け、全ての入力値を検証する必要があります。
ウェブアプリのセキュリティでは、基本として最小権限の原則を守るべきです。これにより、万が一攻撃が成功しても、被害を限定することが可能です。
効果的なMongoDBなどへのインジェクション攻撃は、従来のSQLインジェクションよりも被害が大きくなる恐れがあります。攻撃者はデータを抽出するだけでなく、アプリ上でコードを実行し、不正な管理操作を行ったり、管理者のユーザ情報を乗っ取ってサーバを制御する可能性もあります。特に、NoSQLデータベースは新しい技術であるため、開発者が十分に慣れていないケースが多く、こうしたリスクが高まります。
多くの有名なNoSQL製品はまだ開発初期の段階にあるため、最新版の利用が推奨されます。例えば、MongoDBは以前のバージョンで多くのインジェクション脆弱性が指摘されましたが、最新版ではセキュリティが大幅に強化されています。
NoSQLでもインジェクション攻撃のリスクは完全には排除できません。開発や運用で十分な安全対策を講じたとしても、アプリに脆弱性が残る可能性は常にあります。攻撃を未然に防ぎ、アプリのセキュリティを強化するためには、Wallarmのような包括的で一元管理されたセキュリティソリューションの導入が有効です。
Wallarmを利用すれば、こうした危険を検出し回避することが可能です。プラットフォームは最新の脅威を確認し、警告を発します。オンプレミスのアプリからクラウドネイティブなAPIセキュリティまで、Wallarm API security Platformは、貴社の事業を新たな脅威から守るための重要な要素を提供します。また、どのWAF/WAAPが攻撃検知に優れているかを確認でき、攻撃者がどのような手法を用いているか、現行のセキュリティ対策がどの攻撃を検出しているかを把握する一助となります。
最新情報を購読