インジェクション攻撃

**インジェクション攻撃**(インジェクションこうげき、)とは、コンピュータプログラムが無効なデータを処理した場合に出現するバグを、攻撃者が悪用し不正な命令を実行する攻撃手法である。攻撃者は脆弱性のあるプログラムにソースコードを注入(インジェクト)し、実行過程に変更を加える。インジェクション攻撃が成功した場合、例えばワームの増殖のような、深刻な被害を受けることがある。

## 概要
コードインジェクション脆弱性(インジェクションフロー)は、アプリケーションがインタプリタへ信頼できないデータを送信する場合に生じる。SQL、 LDAP、XPath、NoSQLの問い合わせ、 オペレーティングシステム (OS) のコマンド、XMLの構文解析、SMTPヘッダ、プログラム引数などで最も頻繁に見られる。インジェクションフローはソフトウェアテストよりもの工程で見つけやすい傾向にある。脆弱性検査ツールやファジングが脆弱性発見に役立つこともある。

インジェクション攻撃により、データの損失や改変、責任追跡性の欠如、DoS攻撃などが生じる。時にホストの完全な乗っ取りが起こることもある。

特定の種類のインジェクション攻撃では、単なるユーザ入力に特別な意味を付与してしまい、入力データの解釈に失敗する。このような解釈ミスは**のコメディーのように情報科学の世界以外でも見られる。*Who's on First?*では、固有名詞と一般名詞を区別することに失敗する。同様に、ある種のインジェクション攻撃では、ユーザ入力とシステム命令の区別に失敗する。

インジェクション攻撃の技術は、情報取得のためのハッキング（クラッキング）や特権昇格攻撃、システムへの不正アクセスにおいて広く用いられている。

インジェクション攻撃は悪意を伴う多くの目的に用いられ、次のような例が挙げられる。
* SQLインジェクションによりデータベース内の任意の値を書き換える。SQLインジェクションによる影響はから深刻な機密情報漏洩などにまで及ぶ。
* サーバにPHPやASPなどのスクリプトをインジェクトすることで、マルウェアをインストールしたり、悪意のあるコードを実行したりする。
* UNIXのSetuidバイナリのシェルインジェクション脆弱性やWindows上のサービスを悪用して、スーパーユーザへの特権昇格攻撃を行う。
* HTML/ScriptインジェクションによりWebのユーザを攻撃する（クロスサイトスクリプティング）。
2008年に報告された全ての脆弱性のうち5.66%がインジェクション攻撃に分類されており、記録上最も大きい割合であった。2015年にはこの割合は0.77%へと減少した。

## 有益または非意図的な利用
コードインジェクションは健全な目的にも用いられる。例えば、コードインジェクションによりプログラムやシステムの動作を変更したり微調整したりすることで、悪意のない特定の動作をするようにシステムを「だます」ことができる。
具体例として
* 検索結果ページにおいて本来の設計には出てこない有用な新規カラムを導入する。
* 本来の設計の標準機能において公開されていないデータフィールドを用いて、データのフィルタリング・並べ替え・分類の新しい方法を提供する。
* Dropboxなどのプログラムのように、オフラインプログラムにおいてネットワーク上のリソースにアクセスできる特別な機能を追加する。
* Linuxの動的リンカを用いて、特定のlibc関数と同名の関数を定義し、ライブラリとして関数をリンクし、既存のlibc関数を上書きする。
といったことが挙げられる。

プログラムへの入力がシステム開発者の想定外であるために、ユーザが疑いなくコードインジェクションを行ってしまうことがある。
次のような具体例が挙げられる。
* ユーザが有効だとみなした入力に、特別な意味を持つトークン文字や予約語が含まれるかもしれない (「Shannon & Jason」の「&」や「Bub 'Slugger' McCracken」の引用符があるいはこれに該当するかもしれない)
* あるアプリケーションではうまく処理されるが、送信先のシステムには有害であるような、誤った形式の入力ファイルを送信するかもしれない。

別の有益な利用法としては、脆弱性を修正する目的でのコードインジェクション脆弱性の発見が挙げられるだろう。
このような手法はホワイトハットペネトレーションテストとして知られる。

## 問題の予防
インジェクション攻撃を防ぐために、以下に挙げるような安全な入出力処理をする必要がある。
* 適切に利用すれば任意の文字入力に対してセキュアであるようなAPIを用いる。パラメータ化クエリ(コンパイル済みクエリ、プリペアドステートメント、バインド変数などとも)を用いてユーザデータが解釈実行されることを防ぐことができる。加えてクライテリアAPIや類似のAPIを用いることでコマンド文字列を生成・解釈実行するという考え方から解放される。
* 型システムにより言語間の分離を強制する。
* 既知の適切な値のみをホワイトリスト化するなどの入力バリデーションを行う。
* 危険な文字をエスケープするなど、入力のエンコーディングを行う。例えば、PHPでは、`htmlspecialchars()`関数によりHTMLにおけるテキスト中の特別な文字を安全な出力にエスケープしたり、`mysqli::real_escape_string()`関数によりSQLリクエストに含まれるであろうデータを分離しSQLインジェクションを防いだりする。
* 出力をエンコーディングし、ウェブサイトの訪問者へのクロスサイトスクリプティング(XSS)攻撃を防ぐ。
* `HttpOnly`フラグを立てるとクライアントサイドのスクリプトはHTTP cookieの情報にアクセスできなくなり、ある種のXSS攻撃を防ぐことができる。
* シェルのモジュールをカーネルから分離する。
* SQLインジェクションについては、パラメータ化クエリ、ストアドプロシージャ、ホワイトリスト入力バリデーションなどにより、コードインジェクションの問題を緩和することができる。

上述の解決策は主にウェブのHTMLやスクリプトからサーバサイドアプリケーションへのコードインジェクションについてのものである。
しかし、権限昇格攻撃を引き起こすような、計算機上におけるユーザのコードによるインジェクション攻撃を取り扱うには、別のアプローチが必要である。
インジェクション攻撃を検知・隔離するためのアプローチには次のようなものがある。
* ランタイムイメージのハッシュ検査 - メモリに読み込まれた実行可能イメージの全部または一部のハッシュを生成し、予め記憶済みの期待されるハッシュ値と比較する。
* NXビット - 全てのユーザデータを実行ができないようにした特別な記憶領域に保存する。プロセッサにその領域には一切のコードが存在しないことを伝達し、その領域内のあらゆるデータの実行を拒否させる。
*  - スタックにランダムに値を配置する。実行時、関数が値を返す際にカナリアの値が確認される。カナリアに変更が加えられれば、そのプログラムは実行を停止・終了する。これはスタックオーバーフロー時などに生じる。
* (C言語における) Code Pointer Masking (CPM) - (変更が加えられる可能性のある)コードへのポインタをレジスタに読み込んだ後に、ポインタにマスクをすることで、ポインタが指し示すアドレスを効果的に隠すことが出来る。

## 出典

## 関連項目

## 外部リンク
* CWE-74 インジェクション - JVN iPedia 脆弱性対策データベース
* CWE-89 SQLインジェクション - JVN iPedia 脆弱性対策データベース
* CWE-94 コード・インジェクション - JVN iPedia 脆弱性対策データベース