説明
配列やバッファーの有効範囲外へ書き込もうとする問題です。通常のJava配列は実行時に境界を確認するため、不正なインデックスではArrayIndexOutOfBoundsExceptionが発生し、代入は行われません。ネイティブコードや非安全なメモリAPIによるメモリ破損とは区別してください。
想定される影響
- 処理の中断: 未処理の例外でリクエストやタスクが失敗する可能性があります。
- 一部だけ変更された状態: 例外より前に行った変更は残る場合があるため、エラー処理とトランザクションの範囲を確認する必要があります。
対処方法
- 書き込み前に、インデックスが
0以上かつ配列の長さ未満であることを確認してください。 - 不正な入力には明確なエラーを返してください。例外の発生自体を入力検証の代わりにしないでください。
- コピーする長さや開始位置を外部入力で指定する場合は、計算後の範囲も検証してください。
例
変更前
境界確認だけを示すコントローラーの抜粋です。配列は呼び出しごとに新しく作られ、永続ストレージは更新しません。不正な入力による例外を、適切なクライアントエラー応答へ変換してください。
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配列の例で、同じメモリ破損が起きることを意味しません。
- CVE-2023-1017:TPM参照実装の長さ確認不足によるバッファー外への書き込み
- CVE-2021-21220:ブラウザーの入力検証不足とヒープ破損の連鎖
- CVE-2021-28664:GPUカーネルドライバーの読み取り専用ページへの書き込み