ABV.TAINTED
バッファオーバーフロー - 汚染した入力の配列インデックスが範囲外
ABV.TAINTED は、ユーザーまたは外部デバイスからの、未検証または汚染した入力データが引き起こすバッファオーバーフローをチェックします。このチェッカーは、バッファオーバーフローに関与する入力データが検証されていないコードへの実行パスにフラグを立てます。
脆弱性とリスク
バッファオーバーフローはしばしばアプリケーション攻撃と悪用の元になります。
軽減と防止
汚染した入力からのこれらの攻撃の可能性を避けるには、次のようにします。
- オーバーフローが発生する可能性のある行の前に、必ず検証条件を挿入します。
- 入力の長さ、入力のタイプ、許容される入力値の全範囲、入力の欠落や余剰入力、構文、関連するフィールドの整合性およびビジネスルールとの適合性を含めて、関連する入力プロパティについてすべての可能性を考慮します。
- 誤って負値を許容しないように、範囲の最小値と最大値を必ず検証します。
脆弱コード例
1 #include <stdio.h> 2 void wrapped_read(char* buf, int count) { 3 fgets(buf, count, stdin); 4 } 5 6 void TaintedAccess() 7 { 8 char buf1[12]; 9 char buf2[12]; 10 11 char dst[16]; 12 13 wrapped_read(buf1, sizeof(buf1)); 14 wrapped_read(buf2, sizeof(buf2)); 15 sprintf(dst, "%s-%s\n", buf1, buf2); 16 }
Klocwork は 15 行目について、'dst' への配列インデックスとして未検証入力が使用されていることを指摘する、バッファオーバーフローレポートを生成します。配列 'dst' はサイズ 16 として定義されていますが、13 行目と 14 行目で 22 文字の入力 + 終端の null を生成する可能性があります。この場合は、入力データはバッファサイズとの関連がチェックされていません。このため汚染していると見なされます。
修正コード例
1 #include <stdio.h> 2 void wrapped_read(char* buf, int count) { 3 fgets(buf, count, stdin); 4 } 5 6 void TaintedAccess() 7 { 8 char buf1[12]; 9 char buf2[12]; 10 11 char dst[25]; 12 13 wrapped_read(buf1, sizeof(buf1)); 14 wrapped_read(buf2, sizeof(buf2)); 15 sprintf(dst, "%s-%s\n", buf1, buf2); 16 }
修正コード例では、'dst' のサイズは正しく 25 と定義されました。
関連チェッカー
外部参考資料
- CERT ARR00-C: 配列の仕組みを理解する
- CERT ARR30-C: 範囲外のポインターまたは配列添え字を形成したり使用したりしない
- CERT ARR38-C: ライブラリ関数が無効なポインターを形成しないようにする
- CERT CTR50-CPP: コンテナーインデックスと反復子が有効な範囲内に収まるようにする
- CERT ENV01-C: 環境変数のサイズについて仮定を行わない
- CWE-20: 不適切な入力検証
- CWE-119: メモリバッファの範囲内の操作の不適切な制限
- CWE-125: 範囲外の読み取り
- CWE-129: 配列インデックスの不適切な検証
- CWE-787: 範囲外の作成
- CWE-788: バッファ終了後のメモリ場所へのアクセス]
- CWE-805: 不正確な長さの値でのバッファアクセス
- STIG-ID: APP3510 不十分な入力検証
- STIG-ID: APP3590.1 バッファオーバーフローに脆弱なアプリケーション
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。
拡張機能
このチェッカーは、Klocwork ナレッジベースを利用して拡張できます。詳細については、C/C++ 解析のチューニングを参照してください。