データベース
 Computer >> コンピューター >  >> プログラミング >> データベース

MongoDBにおけるコードインジェクション(NoSQLi)の脅威と対策を徹底解説

初出:2019年3月5日

アプリケーション開発者、データベース管理者(DBA)、あるいはあらゆる分野の技術者にとって、コードインジェクションは常に意識しておくべき脅威です。

MongoDBにおけるコードインジェクション(NoSQLi)の脅威と対策を徹底解説

クラウド環境は堅牢に保ち、データベースへのアクセスも厳しく制限している――しかし、アプリケーションのコードはどうでしょうか。「NoSQLはSQLより安全」と考えられがちですが、NoSQLi(NoSQLインジェクション)のNoは「インジェクション不可能」という意味ではありません。NoSQLも他のデータベースと同様に、コードインジェクションに対して脆弱になり得ます。コードインジェクションへの備えを怠るのは、玄関にセキュリティシステムを設置しながら、裏窓を開けっ放しにしているようなものです。

コードインジェクションとは?

コードインジェクションとは、検証されていないデータが脆弱なプログラムに注入され、アプリケーションコードとして実行されてしまう攻撃手法です。その結果は往々にして深刻な被害をもたらします。

SQLi(SQLインジェクション)は最も一般的なインジェクション手法の一つで、登場から10年以上経った今でも依然として猛威を振るっています。インジェクションの問題はデータベース言語に特有のものではなく、SQLやNoSQL以外にも、XPath®、XMLパーサー、SMTPヘッダーなど、さまざまな文脈で発生し得ます。その深刻度において、コードインジェクションはリモートコード実行(RCE)に匹敵します。ペネトレーションテストの世界でいうところの「ゲームオーバー」画面です。

自社アプリケーションにおけるNoSQLiを検知・防止することは極めて重要です。対策されていないインジェクション経路を放置すれば、ユーザーの安全性が脅かされ、ビジネスを終焉させかねない信頼の失墜につながりかねません。幸い、その仕組みを理解すれば、サービス内のNoSQLi脆弱性を検知・防止するための具体的な対策を講じることができます。

NoSQLiの簡単な事例

通常、MongoDB®は安全なBSONクエリ構築ツールを使って生成されたバイナリJSON(BSON)データを受け入れます。しかし特定の状況下では、シリアライズされていないJSONやJavaScript(JS)式、たとえば$where演算子なども受け付けてしまいます。

SQLと同様に、この$where演算子はNoSQLにおける潜在的なインジェクションの温床となります。ただしSQLとは異なり、NoSQLの$whereは条件式をJSで記述します。つまり、SQLの機能範囲に限定されることなく、JSの持つ強力な表現力をフルに使って悪意あるクエリを組み立てることが可能なのです。

公開リポジトリにあるMongoDBインジェクション文字列の一覧を見てみると、SQLや他の言語における類似の脆弱性と共通する、いくつかの典型的な攻撃戦略が見えてきます。

たとえば、古典的な1 == 1という式を使ってクエリに真値を返させ、隠された(または管理者レベルの)リソースや権限を読み取ろうとする手法があります。

$Where: '1 == 1'

また、ブラインドインジェクション戦略を模倣した手法もあります。sleep()関数を使ってデータベースの応答を意図的に遅延させ、巧妙に設計されたフィルタと組み合わせることで、機密情報を一つずつ列挙する副作用を作り出します。

';sleep(5000); ';it=new%20Date();do{pt=new%20Date();}while(pt-it<5000);

そしてもちろん、プレーンなデータ流出攻撃もあります。これは注入されたクエリが、機密情報そのものを直接照合・取得しようとするものです。

' && this.password.match(/.*/)//+%00

最初の例を除き、残りの2つの例は$where演算子を使用していません。JS形式の便利な式が足掛かりになくても、NoSQLデータベースへの攻撃は成立してしまうのです。

NoSQLiを防ぐために

NoSQLi耐性のあるアプリケーションアーキテクチャを構築するには、いくつかの基本的な戦略があります。これらは、一般的なアンチインジェクションのベストプラクティスと一致しており、決して意外なものではありません。

MongoDB / NoSQLiも例外ではない

コードインジェクションはSQL固有の問題だと捉え、他の文脈への応用可能性を過小評価する人が少なくありません。本記事を通じて、NoSQLiが現実に存在する脅威であることをご理解いただけたなら幸いです。これは「MongoDB will not prevent NoSQL injections in your Node.js app」のような記事でも詳しく取り上げられており、十分に文書化された事実です。

検証されていないユーザーデータを信用しない

セキュリティの観点から、ユーザー入力を信用してはいけません。

セキュリティ業界では耳にタコができるほどの定番アドバイスですが、すべての入力には悪意のある調査が行われることを前提とすべきです。先ほどの$whereの例は、$where: 検証されていない入力といった書き方がなぜ危険なのかを明確に示しています。フィルタをユーザーに露出させてしまった時点で(それだけでも十分にまずいのですが)、ユーザーが検証されていないデータをより大きなクエリに持ち込んでいるという事実自体が、まったくのベストプラクティス外なのです。

言語や連携技術の特性に注意する

NoSQLiがインジェクションに対して特別に免疫があるわけではない(むしろ多くの同じタイプの攻撃を受ける)からといって、NoSQLi特有の、あるいはNoSQL DB上に構築された言語やコンポーネント特有の攻略手法が存在しないわけではありません。顕著な例として、$whereはPHP変数としても解釈される書式であるため、PHPアプリケーションを基盤とするNoSQLデータベースでは、$whereに格納された悪意ある文字列インジェクションのシナリオまで考慮する必要があります。

まとめ

繰り返しになりますが、NoSQLiのNoは「インジェクション不可能」を意味しません。NoSQLはSQL、SMTPヘッダー、XMLなどと同じように、コードインジェクションに対して脆弱であり、「アプリケーションコードではないものをアプリケーションコードとして扱ってしまう」という、多くのテクノロジーを悩ませる落とし穴の影響を受けます。

本記事が、NoSQLiおよびそれがビジネスに与える意味についての理解を深める一助となれば幸いです。これからは、インジェクションの発生を抑え、被害の拡大を防ぎ、影響を最小限にとどめるプロセスへとコードを導くことができるでしょう。アプリケーションとホスティング環境のセキュリティ確保のためMongoDB運用に関するアドバイスが必要な場合は、Rackspace ObjectRocketの経験豊富なDBAがお手伝いいたします。

Rackspace DBAサービスの詳細については、ぜひご覧ください。

コメントやご質問がある場合は、Feedbackタブをご利用ください。また、Sales Chatをクリックいただければ、すぐにチャットで会話を始めることも可能です。

  1. MongoDB Compass(コンパス)とは?特徴・エディション・基本的な使い方を徹底解説

    本記事では、MongoDB®の公式GUIツールであるMongoDB Compassについて、その概要からインストール方法、基本的な操作まで詳しく解説します。 MongoDB Compassの概要 MongoDB Compassは、MongoDBクエリ構文の専門知識がなくても、視覚的なインターフェースを通じてデータベースを分析・理解できる強力なツールです。データの可視化による探索だけでなく、以下のような高度な機能も備えています。 クエリパフォーマンスの最適化 インデックスの管理 ドキュメントバリデーション(スキーマ検証)の実装 これにより、開発者だけでなく、運用担当者やデータアナリストなど、

  2. MongoDBで未使用のインデックスを検索する方法 ― $indexStats活用の6つのポイント

    MongoDBはバージョン3.2以降、すべてのインデックスに対して使用状況の統計情報を追跡しています。これらの統計へアクセスするために、MongoDBは$indexStatsアグリゲーションパイプラインステージを提供しています。この記事では、MongoDBで未使用のインデックスを特定する際に押さえておきたい6つのポイントを解説します。例えば、次のコマンドを実行すると、コレクション「test.foo」のインデックス統計を取得できます。db.foo.aggregate( [ { $indexStats: { } } ] )参考: $indexStatsに関する公式ドキュメント$indexStats