システム開発とセキュリティ(2)
セキュアC/C++プログラミング
BOFを引き起こす関数
C 言語および C++ 言語のライブラリ関数にはバッファオーバーランを引き起こしかねない関数が多数存在する
バッファオーバーラン問題は、C 言語やC++ で書かれたパッケージソフトウェアが抱えるセキュリティ脆弱性の中で最も頻繁に報告されるものの一つ
バッファオーバーラン(BOF)とは元々、コンピュータのメモリ上の領域(バッファ)よりも大きなデータが渡されているのにプログラムがそれを見逃して領域あふれ(オーバーラン)が起きてしまうことを指す。こうした欠陥を悪用すると、そのプログラムのメモリ上に任意のマシン語プログラムを送り込み実行させることが可能になる場合がある。標的プログラムが高い権限で動作するものだった場合、その権限を乗っ取って対象コンピュータを意のままに操ることができてしまう
関数 | 危険度 | 代用関数 及び 対策方法 |
---|---|---|
gets() | 高 | fgets() |
strcpy() | 高 | strncpy() |
strcat() | 高 | strncat() |
sprintf() | 高 | snprintf() or format内で精度(格納する文字列の最大長)を指定する |
scanf() | 高 | format内で精度を指定する |
sscanf() | 高 | format内で精度を指定する |
fscanf() | 高 | format内で精度を指定する |
vfscanf() | 高 | format内で精度を指定する or 独自にデータサイズのチェックを行う |
vsprintf() | 高 | format内で精度を指定する |
vscanf() | 高 | format内で精度を指定する or 独自にデータサイズのチェックを行う |
vsscant() | 高 | format内で精度を指定する or 独自にデータサイズのチェックを行う |
getchar() | 中 | バッファ境界をチェックする |
fgetc() | 中 | バッファ境界をチェックする |
getc() | 中 | バッファ境界をチェックする |
文字列処理
なんらかのエンコード形式で構成された文字列の解釈を行う際、そのフォーマットやルールを十分に把握しておく。 そうしないと予期しない結果を生む恐れがあり、それが原因で不正なデータの通過を許してしまうことがある。
文字列の解釈
プログラム内で文字列処理を行うケースとして、エンコード表現を含む文字列の解読処理が挙げられる。たとえば、WebアプリケーションにおいてWebページ間で受け渡したいデータをURLのクエリストリングに含める場合のデータは、「URLエンコード」と呼ばれる形式で表現される。CGIプログラムでURL エンコードされたデータを利用する場合、まずこの表現をデコードすることから始まる。URLエンコードをはじめ、各種の形式のデータのデコードを試みる場合には、注意しなければならないポイントが存在する。これらへの考慮が足りないと、不正なデータを見逃すなどの問題を起こすことがある。
注意を要する文字
- NULL文字(文字コードによって0x00,
0,%00などと表記する)
- 空白文字(0x20,
s,%20)
- 改行文字(0x0a,
n,%0a)
- タブ(0x09,
t,%09)
関数の使用によって文字列の区切りや終端を示すものとなる
URLエンコード
URIにおいて使用できない文字を使う際に行われるエンコード(一種のエスケープ)のこと。アルファベット、数字および一部の記号以外のデータは「%xx」(xx は2桁の16進数)の形式で表現されて伝送される。
デコードの重複
複数回のデコード処理が重複して実行されることで問題が発生することがある
デコードと分解の順序
キーワードを切り出す処理を実行した後に、各キーワードに対してデコード処理を行うようにする。デコード処理と部分列の切り出しの順序を誤ると、予期せぬ結果を生むことがある
エンコード文字列に「%26」や「%3D」といったデータが含まれる場合、この「%26」,「%3D」に対してデコード処理を行うとそれぞれ「&」,「=」に変換される。これは、クエリストリングの区切り文字と同じであるため、キーワードを切り出す処理が、正常に動作しなくなってしまう
サブシェル呼び出し(system()関数)
- 既存のコマンドをsystem()関数で呼び出して新たなプログラムの部品として利用する場合、与えるコマンド文字列に含めるデータは十分なチェックをパスしたものでなくてはならない
データに、背後で起動されるサブシェルにとって特別な意味をもつ文字が含まれている可能性がある - PATH環境変数に依存したプログラム呼び出しを避ける
悪意あるユーザがPATH環境変数を書き換えているおそれがあるから
 

