第8章 入力検査
入力検査の概要
ソフトウェアに対する攻撃の多くは、不正な入力データがプログラムに侵入する形態をとる。
- ファイル名に不正なディレクトリ修飾を混入するディレクトリトラバーサル攻撃
- 文字列データ領域にマシンコードを侵入させるバッファオーバーフロー攻撃
- データベースの侵害が起こるSQL注入攻撃
- リソースの大量消費をおこすサービス妨害攻撃 等

検査のふたつの方式
入力検査の方式には、ホワイトリスト方式とブラックリスト方式のふたつがある。
- ホワイトリスト方式
──受理するデータの条件を記述し、該当しないものを拒絶する - ブラックリスト方式
──拒絶するデータの条件を記述し、該当しないものを受理する
ブラックリスト方式で注意すべき点は、拒絶すべきデータの条件に漏れがある場合や、新たな攻撃手法が開発された場合、攻撃者に入力検査を迂回されるおそれがあることである。可能ならば、ホワイトリスト方式を採用するのがよい。
その一方でホワイトリスト方式の注意点は、入力データの仕様によってはホワイトリストとして条件を記述できないケースがある点である。例えば、すべて英字からなる文字列についてほとんどすべての綴りを受け入れるがいくつかのキーワードのみは避けたいという仕様の場合、ホワイトリスト方式は使えない。
どちらか一方のみで対処するというのではなく、そのデータの仕様に最も合致した形でこれらふたつを組み合わせるとよい。
入力検査の種類
入力検査の種類は、概ね次のようなものである。実装にあたっては、可能な限り複数の検査を組み合わせるのがよい。
(1) 単項目検査
ひとつの入力データ項目のみを調べる検査。単項目検査にはさらに次の種類がある。
- 桁数検査
値を構成している文字数(あるいはバイト数)が妥当であるか否かの検査 - 文字種検査
値を構成している文字ですべて妥当であるか否かの検査 - 範囲検査
値が所定の下限値と上限値の間に収まっているか否かの検査。
値は数値の場合と文字列値の場合の両方がある。文字列を数値に変換する際には注意が必要である。C言語のatoi()関数、Perl、PHP等における自動型変換等を用いると、不正な文字を見逃すおそれがある。範囲検査を行う場合も、文字種検査を省略すべきでない。 - リスト検査
値がリストに載っているか否かの検査。リストはプログラム中に直接記述する場合や、データベースの読み出しによって得る場合等がある。
これらはおおむね上記の配列の順序で適用する。
(2) 組合せ検査
複数の入力データ項目の組み合わせが所定の条件を満たしているか否かの検査。組合せ検査は、用途に応じて次のふたつに分かれる。
- フォーマット検査
複数のデータ項目を収容しているファイルやバイト列が所定の形式に従っているか否かの検査。「長さ」「項目数」等の記述子の妥当性、記述子と収容内容の整合性等を検査する。収容されている値のうち他の項目に影響を及ぼさなものは調べない - 値の組合せ検査
複数項目の値の組合せの妥当性の厳密な検査
(3) ロジック検査
複雑なロジックを試行して妥当な結果が得られるか否かによって判定を行う検査。
警戒すべき入力経路
プログラムが不正なデータの投入を警戒すべき入力経路には次のものがある。カテゴリごとにおおよその危険度を示した。
- リモートからの入力 <危険度・大>
1) ネットワーク入力
2) ネットワーク受信ファイル - ローカルの入力 <危険度・中>
3) ローカル端末入力 - マシン内のデータ <危険度・小>
4) 環境変数
5) コマンドライン引数
6) ローカルファイル
7) ローカルデータベース
これらの経路から入力するデータはどれも検査の必要がある。
(1) ネットワーク入力の検査
ネットワークを通じてデータを受け取るプログラムに対しては、そのネットワークに接続可能なユーザ全員が攻撃データを送りつける機会をもつ。
サーバプログラムは普通のクライアントの振りをしたコンピュータから攻撃を受け、クライアントプログラムは善良なサーバの振りをしたマシンから攻撃を受けるおそれがある。また、両者が正規のものであっても通信が途中で改ざんされ、攻撃データが入り込むおそれがある。
ネットワーク入力は最も入力検査を強化すべき入力経路である。
(2) ネットワーク受信ファイルの検査
ネットワーク受信ファイルを読み込む場合には、フォーマット検査を厳密に行う。画像、音声、動画等のマルチメディアコンテンツ系のファイルは複雑なフォーマットをもっている。このようなファイルの内部にはバッファオーバーフロー攻撃データや整数オーバーフロー攻撃データが仕込まれるおそれがある。
マルチメディアコンテンツを再生するライブラリそのものによるファイルフォーマット検査にはしばしば不備が見つかるため、ライブラリを使うアプリケーション自身が自衛のための検査をする必要がある。
ネットワーク受信ファイルの検査については『受信ファイルの検査』を見られたい。
(3) ローカル端末入力の検査
ローカル端末にアクセス可能なユーザは、ソフトウェアに対してさまざまな攻撃データを入力し得る。プログラムは、ローカル端末からの入力を十分に検査する必要がある。
(4) 環境変数の検査
多くのプラットフォームでは環境変数が用いられている。環境変数はアプリケーションプログラムが直接参照するものもあれば、ロードするライブラリの制御等、見えないところで効果をおよぼすものもある。これらが不正に設定されているとソフトウェアが侵害されるおそれがある。ローカルコンピュータにログイン可能なユーザは、環境変数の値を細工することが可能である。
環境変数の検査については『環境変数の検査とリセット』を見られたい。
(5) コマンドライン引数の検査
ローカルコンピュータにログイン可能なユーザは、細工した値をコマンドライン引数に与えてプログラムを呼び出すことが可能である。プログラムは、コマンドライン引数を十分に検査する必要がある。
(6) ローカルファイルの検査
ローカルファイルを読み込む際にもいくつか注意すべき点がある。
ローカルファイルの検査については『ファイルの別名検査』を見られたい。
(7) ローカルデータベースの検査
ローカルデータベースから得られた値であっても、そこに格納される時点で外部から攻撃パターンを受け入れているおそれがある。プログラムは、ローカルデータベースからの入力値を十分に検査する必要がある。