
CVE-2025-6554の概念実証エクスプロイト。V8 JavaScriptエンジンの脆弱性で、オプショナルチェーンを介して未初期化の「Hole」値への不正アクセスを可能にし、型混乱とメモリ操作を引き起こします。
CVE-2025-6554 は、Chrome の V8(JavaScript エンジン)インタプリタにおける脆弱性です(オプショナルチェイニングを含む式内で意図しない変数における「Hole」チェックの不適切な制御)。POC(CVE-2025-6554-POC.JS)は、変数使用前の「Hole」検証メカニズムの欠陥を探り、通常は参照エラーでブロックされる未初期化値の読み取りを可能にします。
function leak_hole() {
let x;
delete x?.[y]?.a;
return y;
let y;
}
function pwn() {
let hole = leak_hole();
%DebugPrint(hole);
}
pwn();
let x; と let y; はローカルスコープの変数を宣言します。
delete x?.[y]?.a の行では、オプショナルチェイニングを使用して安全にネストされたプロパティにアクセスしています。
問題点: 変数 y が宣言される前に使用されており、本来は参照エラーが発生するはずですが、パッチ前の V8 ではこれが暗黙のうちに失敗し、TDZ(Temporal Dead Zone)変数のための特殊値「The Hole」を取得できてしまいます。
コード内の return y は、y がまだ TDZ にあるためアクセス可能であってはなりません。しかし、この失敗によりアクセスできてしまいます。
TDZ にある変数へのアクセスを防ぐメカニズムは ThrowReferenceErrorIfHole です。
パッチ前は、このメカニズムは delete x?.[y]? の間で一度だけ呼び出されていました。
V8 は内部的に、変数 y は「ホールではない」と既に検証済みであるとマークしましたが、この検証は制御されたスコープから漏れており、そのため return y の際に再評価されませんでした。
パッチでは、return y に ThrowReferenceErrorIfHole の呼び出しを追加し、宣言文の前に y にアクセスしようとする試みが正しくエラーを発生させるようにしました。
この検証は OptionalChainNullLabelScope に含まれる ScopeInfoCheckEtScope によって保証されました。
delete x?.[y]?. → Y へのアクセスを試行(未初期化)→「Hole」チェックの失敗
→ Y が値として漏洩 → return y; →「Hole」の値を取得 → DebugPrint で露呈
攻撃者はこの「Hole」を取得することで、V8 エンジンの内部状態を推測でき、以下のような攻撃を容易にします: