SV.TAINTED.INDEX_ACCESS
配列インデックスの未検証の入力
入力がユーザーまたは外部環境から受け入れられるときは常に、入力のタイプ、長さ、書式、および範囲を検証してから使用する必要があります。適切に検証されるまでは、そのデータは汚染していると言われます。SV.TAINTED ファミリーチェッカーは、コードでの汚染データの使用箇所を探します。
SV.TAINTED.INDEX_ACCESS チェッカーは、汚染データを使用して配列にアクセスするコードにフラグを立てます。
脆弱性とリスク
コードへの入力が適切に検証されないと、攻撃者は入力をアプリケーションが予期しない形で作成することができます。意図しない入力を受け取ると、制御フローの改変、任意リソースの制御、および任意のコードの実行につながる可能性があります。この種のチャンスがある場合、攻撃者は次のことを行えます。
- 予期しない値を提供し、プログラムクラッシュを引き起こします。
- 過剰なリソース消費を引き起こします。
- 機密データを読み取る
- 悪意のある入力を使用して、データを変更したり制御フローを改めたりします。
- 任意のコマンドを実行します。
ユーザーが配列インデックスとして指定する値を使用すると、インデックスの領域外脆弱性につながる可能性があります。この脆弱な関数で、任意のメモリからの読み取り、作成が可能である場合、アプリケーションの不安定性につながったり、注意深く練られた攻撃ではデータ開示脆弱性やコード挿入につながることがあります。
軽減と防止
汚染入力エラーを回避するには:
- パラメーターや引数、クッキー、ネットワークから読み取られる入力、環境変数、逆 DNS ルックアップ、クエリ結果、ファイル名、データベース、および外部システムという、信頼されていない入力がソフトウェア内に入り込む可能性がある領域すべてを把握します。
- ブラックリスト、つまり「既知の不良な」戦略だけを信頼するのではなく、ホワイトリスト、つまり「既知の良好な」ポリシーを入力に使用します。
- 入力の該当するプロパティがすべて検証済みであることを確認します。これには、長さ、タイプ、範囲、欠落しているか余計な入力、構文、および一貫性が含まれます。
- アプリケーションのクライアント側でセキュリティチェックが実行される場合、サーバー側で複製されることを確認します。
- アプリケーションで複数ソースからの入力が組み合わされる場合、ソースの組み合わせが完了したら検証を行います。
脆弱コード例
void getSize()
{
unsigned num, size;
int i;
scanf("%u %u",&num, &size);
sizes[num - 1] = size;
}
Klocwork は 6 行目で指摘レポートを生成し、未検証の整数値 'num' が 5 行目での 'scanf' の呼び出しを通じて渡され、6 行目での 'scanf' の呼び出しを通じて配列へのアクセスに使用できることを示します。この場合、SV.TAINTED.INDEX_ACCESS チェッカーは、配列へのアクセスに使用される汚染されている可能性のあるデータにフラグを立てます。 これは、悪意のあるユーザーによって悪用される可能性があります。
修正コード例
void getSize()
{
unsigned num, size;
int i;
scanf("%u %u",&num, &size);
if (num > sizeof(sizes)/sizeof(*sizes)) return;
sizes[num - 1] = size;
}
修正された例では、整数 'num' が 6 行目で検証されてから、配列へのアクセスに使用されます。
関連チェッカー
外部参考資料
- CERT ARR00-C: 配列の仕組みを理解する
- CERT ARR30-C: 範囲外のポインターまたは配列添え字を形成したり使用したりしない
- CERT CTR50-CPP: コンテナーインデックスと反復子が有効な範囲内に収まるようにする
- CERT INT04-C: 汚染された情報源から取得した整数値に制限を強制する
- CWE-20: 不適切な入力検証
- CWE-129: 配列インデックスの不適切な検証
- CWE-788: バッファ終端後部のメモリ位置のアクセス
- CWE-805: 不正確な長さの値でのバッファアクセス
- CWE-896: なし
- OWASP A3:2021 インジェクション
- STIG-ID: APP3510 不十分な入力検証
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。