コードインジェクション

はじめに
本稿では、外部から受け取った文字列をプログラムコードとして実行してしまうコードインジェクションと呼ばれる脆弱性について解説します。
コードインジェクションとは
コードインジェクションとは、Webアプリケーションにおいて外部から入力されたデータをプログラムコードとして実行してしまうことで、攻撃者によって作成されたコードのサーバー上での実行が引き起こされてしまう脆弱性です。
攻撃者によって作成された任意のコードが実行されてしまうため、非常に危険性が高い脆弱性となります。
コードインジェクションが発生する典型的なコードとして、外部から受け取ったデータをPHPやNode.jsのeval関数に渡すというものがあります。
<?php
// 脆弱なコード例
$v = $_GET['value'];
$n = $_GET['number'];
$price = floor(eval("return $v * $n * 1.1;"));
?>
このコードは、URL内のvalueパラメーターとnumberパラメーターそれぞれで商品の税抜き価格と個数を受け取り、消費税分の10%を加えた金額を算出するということを想定した処理ですが、文字列として受け取った金額や個数を数値として掛け算するためにeval関数を使っています。
このとき、攻撃者がvalueパラメーターやnumberパラメーターに数値だけでなくPHPのコードを含めることで、eval関数内でそのコードが評価実行されることになるので、攻撃者はどのようなコードでも自由にサーバー上で実行できることになります。
コードインジェクションの対策
コードインジェクションの対策としては、文字列を与えるとコードとして実行される機能に対して、外部から受け取った文字列は絶対に与えないようにします。
evalのように直接的に文字列をコードとして実行する機能だけでなく、受け取った文字列をファイルに保存した際に外部モジュールをロードする機能を通じてそのファイルをロードしないようにも注意する必要があります。
具体的に気を付ける機能としては、例えば以下のようなものがあります(これが全てではありません)。
- PHP: eval / require / include 等
- Node.js: eval / Functionコンストラクタ / vmモジュール / require / import 等
- Java: Classクラス等によるリフレクション
これらの機能に対しては、外部から受け取った文字列は与えないように、また外部から受け取った文字列が保存されたファイルをプログラムとしてロードすることがないよう徹底します。
まとめ
本記事では、外部から受け取った文字列をコードとして実行してしまうことで発生する脆弱性、コードインジェクションについて解説しました。コードインジェクションは極めて危険な脆弱性ですので、絶対に発生させないよう対策を徹底する必要があります。
下の表では、実装しようとする機能に対して発生する可能性のある脆弱性や、その機能に対して発生し得る攻撃手法などをまとめています。表の左側にはWebアプリケーションで実装されるそれぞれの機能、表の右側にはその機能を実装するときに発生しがちな代表的な脆弱性や攻撃手法を掲載しています。
どのような機能の実装時にどのような脆弱性を作りこんでしまうのかの参考にしてください。
| 実装する機能 | 発生する脆弱性や関連する攻撃手法 | |
|---|---|---|
| ログイン処理 | 認証機能の突破、セッションに関連する問題 | |
| ユーザーごとの機能 | 認可制御の問題、強制ブラウズ | |
| データの 入出力 |
全体 | パラメータ操作、コードインジェクション |
| HTMLの出力 | クロスサイト・スクリプティング(XSS) | |
| データベースへの アクセス |
SQLインジェクション | |
| ファイルへのアクセス | ディレクトリトラバーサル | |
| 外部コマンドの実行 | OSコマンドインジェクション | |
| サーバー上で状態が変化する処理 | クロスサイト・リクエスト・フォージェリ(CSRF) | |
| エラー処理 | エラーメッセージによる情報漏えい | |
| サーバーからのリクエスト発行 | サーバーサイド・リクエスト・フォージェリ(SSRF) | |
| 正規表現の使用時 | 正規表現によるDoS(ReDoS) | |
| アプリケーション全体 | レースコンディション、バックドアやデバッグモードの残存 | |

