範囲外への書き込み

範囲外への書き込み

説明

配列やバッファーの有効範囲外へ書き込もうとする問題です。通常のJava配列は実行時に境界を確認するため、不正なインデックスではArrayIndexOutOfBoundsExceptionが発生し、代入は行われません。ネイティブコードや非安全なメモリAPIによるメモリ破損とは区別してください。

想定される影響

  • 処理の中断: 未処理の例外でリクエストやタスクが失敗する可能性があります。
  • 一部だけ変更された状態: 例外より前に行った変更は残る場合があるため、エラー処理とトランザクションの範囲を確認する必要があります。

対処方法

  1. 書き込み前に、インデックスが0以上かつ配列の長さ未満であることを確認してください。
  2. 不正な入力には明確なエラーを返してください。例外の発生自体を入力検証の代わりにしないでください。
  3. コピーする長さや開始位置を外部入力で指定する場合は、計算後の範囲も検証してください。

例

変更前

境界確認だけを示すコントローラーの抜粋です。配列は呼び出しごとに新しく作られ、永続ストレージは更新しません。不正な入力による例外を、適切なクライアントエラー応答へ変換してください。

java
@GetMapping("/update")
public void updateData(@RequestParam int index, @RequestParam int value) {
    int[] data = new int[10];
    data[index] = value; // 境界確認なし
}

変更後

java
@GetMapping("/update")
public void updateData(@RequestParam int index, @RequestParam int value) {
    int[] data = new int[10];
    if (index >= 0 && index < data.length) {
        data[index] = value; // 境界を確認済み
    } else {
        throw new IllegalArgumentException("Invalid index");
    }
}

説明:

  • 変更前: indexを検証しないため、範囲外の値ではArrayIndexOutOfBoundsExceptionになります。このJava配列への代入で、配列外のメモリが破損することはありません。
  • 変更後: 範囲内のインデックスだけを使い、それ以外はIllegalArgumentExceptionで拒否します。

関連CVE

以下は他のプラットフォームにおけるメモリ書き込みの事例です。上のJava配列の例で、同じメモリ破損が起きることを意味しません。

参考資料