セキュリティ問題のほとんどはインジェクション問題と考えることができます。インジェクション問題として考えられるセキュリティ問題のモデル化を考えます。
実際のセキュリティ問題は多種多様で非常に複雑ですが、シンプルなモデルで考えると理解り易く、多くのセキュリティ問題を体系的に理解できます。
そもそもインジェクション問題とは?
インジェクション問題とは「開発者が意図しない不正な操作の”挿入(インジェクション)”を攻撃者が行える問題」と考えることができます。インジェクション問題の代表例といえるSQLインジェクションでいうと、以下のようなコードがインジェクション攻撃に脆弱になります。
$result = pq_query("SELECT * FROM mytable WHERE id = {$_GET['id']}")
$_GET[‘id’]に”1 OR 1 = 1″が設定されると、mytableの全てのレコードが出力される可能性があります。
アプリケーションを作る場合にはSQLデータベース、HTML、HTTPやSMTPなど様々な規格の処理系のデータ処理を行います。利用する処理系に一文字でも意味のある文字がある場合はインジェクションが可能になる、と考える必要があります。
例:
- 空白文字でトークンが分割される
- 改行で命令やコンテクストが切り替わる
インジェクション問題と考えられていないセキュリティ問題
例えば、強制ブラウズ、認証漏れ、クロスサイトリクエストフォージェリ、権限昇格などはインジェクション問題とは考えられていません。
- 強制ブラウズ – 特定のリソース(ファイルやプログラムの機能など)に直接アクセスできる問題
- 認証漏れ – 本来認証機能で制御されるべきリソースが認証機能で保護されず、アクセスできる問題
- クロスサイトリクエストフォージェリ – 認証機能では保護されているが、認証済みブラウザのセッションを経由して、攻撃者の意図する機能にアクセスできる問題
- 権限昇格 – 本来認可機能で制御されるべきリソースが認可機能で保護されす、アクセスできる問題
これらのインジェクション問題と考えられていないセキュリティ問題も「開発者が意図しない不正な操作の”挿入(インジェクション)”を攻撃者が行える問題」と考えるとインジェクション問題として考えることが可能です。
インジェクション問題のパターン
インジェクション問題は2種類のパターンに分類できます。
- 直接インジェクション
- 間接インジェクション
直接インジェクションは解りやすいパターンです。攻撃者が直接Webアプリケーションを攻撃できるパターンです。これは直感的に解りやすいインジェクションパターンです。
直接インジェクション
図:直接インジェクションの基本パターン
直接インジェクションには
- 強制ブラウズ
- 認証漏れ(権限チェック不足の認可漏れも同じ)
- 直接SQLインジェクション
- 直接コマンド実行
- DoS(サービス不能攻撃)
などがあります。
間接インジェクション
間接インジェクションは何らかのシステムを経由してインジェクション攻撃を行うパターンです。多くの場合は外部システムからの入力を信頼できる勘違いしたことにより発生します。言い換えると”信頼できる”と考えられるシステムの権限/信頼を利用して攻撃が行われます。
間接インジェクションは何らかのシステムを経由してインジェクションを行う攻撃パターンで、直接インジェクションに比べ解りづらいインジェクションパターンです。しかし、インジェクションつまり「開発者が意図しない不正な操作の”挿入(インジェクション)”を攻撃者が行える問題」であることは変わりません。
図:間接インジェクションの基本パターン
間接インジェクションには
- クロスサイトスクリプティング – ブラウザを経由してインジェクション
- クロスサイトリクエストフォージェリ – ブラウザを経由してインジェクション
- 間接SQLインジェクション – データベースレコードなどシステムに保存されたデータを経由してインジェクション
- 間接コマンド実行 – データベースレコードなどシステムに保存されたデータを経由してインジェクション
- 権限昇格 – アプリケーションの権限チェックなどの不備を利用するリクエストを送信して不正な処理を行う
- XXE – XMLファイル処理系の外部参照ファイルを利用してインジェクション
- DoS – サービス不能攻撃
などがあります。権限昇格やシンボリックリンク攻撃はインジェクション攻撃と考えられることはあまりないと思いますが、「開発者が意図しない不正な操作の”挿入(インジェクション)”を攻撃者が行える問題」と考えると間接インジェクションのパターンに当てはまります。
間接インジェクションを行う場合、中継する”モノ”は攻撃に利用できるモノであれば何でも構いません。
- ブラウザ
- データベース
- ファイル
- サービス
- その他、アプリケーションが利用する外部システム何でも
- アプリケーション自体やライブラリ
- 内部リダイレクトなどのアプリケーション機能
- XML処理系
- 画像処理系
- その他、様々な処理で攻撃に利用できるもの何でも
などが攻撃に利用されます。アプリケーション自体を中継システムとして利用する攻撃は攻撃者視点から見ると直接攻撃と考えられますが、アプリケーションプログラマ視点から見ると間接攻撃と考えた方が解りやすいです。
例えば、内部的なリダイレクトはアプリケーションのコードによってリクエストされますが、そのリクエストは本当に”妥当”(つまり安全にアプリで生成されたモノ)か、自分のアプリが中継システムとして利用されることがないか?と考えると問題を防止することができます。
アプリケーション自体が間接インジェクションを行う中継システム(攻撃を中継するシステム)になることもあります。
- XXE
- オープンリダイレクト
- ユーザー入力パラメータを含む他のシステムへのリクエスト
がその代表例で、これらは他のシステムへのリクエストフォージェリ攻撃に利用されます。
インジェクションパターンに当てはまらない物
直接/間接インジェクションのどちらにも当てはまらない物も考えてみます。
- レースコンディション
直ぐに思い付く物はレースコンディションです。アプリケーションのロジックエラーによる間違いにはインジェクションパターンにならない物があります。CWEを見てどれがインジェクションパターンであるかどうか、分類すると見つかります。しかし、多くのセキュリティ問題はインジェクションパターンに適合します。
従って、攻撃者が送ったまたは送らせた意図しないリクエスト/リソースがアプリケーションに送られないか?とインジェクションパターンを考えるだけで、セキュリティ問題の多くに対応できることになります。
まとめ
インジェクションと一括りにまとめるとインジェクション攻撃の種類が多過ぎて解りづらいです。しかし、インジェクションを攻撃パターンとして理解し、直接インジェクションと間接インジェクションの2パターンで分類/理解すると、知らない個別のインジェクションパターンにも対応できるようになります。共通パターンを理解した上で、個別対策を知ると応用できるようになります。
例えば、今年のBlackHatでは、テンプレートを動的に生成している場合にユーザー入力を使っているとリモートから任意コードの実行を許す、とした発表がありました。テンプレートシステムは言語と言えます。意味のある文字列の塊です。ユーザー入力を利用してテンプレートを生成する操作は明らかにインジェクションパターンに適合します。
「テンプレートを使った任意コード実行が可能なのか!」と新しい問題のように感じるかも知れませんが、インジェクションパターンを理解していればインジェクション攻撃ができて当たり前のパターンであることが解ります。
個々のインジェクション脆弱性がどのようなケースで発生し、どのように防止するのか?これを理解することも重要ですが、「インジェクションパターン」を理解することも重要です。インジェクションパターンを理解すれば「こんなインジェクション方法もあったのか!」と驚くことはなくなり、予め自分で考え対策できるようになります。
個別のインジェクション攻撃は多数存在します。想定外が無いように入力バリデーションを行った上で、個別のインジェクションに対応すると効果的です。
参考: