From JavaScript to Renderer Code Execution: Three V8 Vulnerabilities and Two v8CTF Flags
Attack Techniques & Methods2026-11-03, 07:34
Using the
dfs-large1 tool, researchers uncovered three vulnerabilities in V8: two memory corruption vulnerabilities and one sandbox escape. They were combined into two separate exploit chains, each achieving code execution in Chrome’s renderer process.1. CVE-2026-78938 — a type confusion vulnerability in
Promise.prototype.finally. The internal helper functions were non-strict and constructable. Using .caller made it possible to obtain a reference to one of these functions, while invoking it with new could return a number. TurboFan assumed that the result of new was always an object and eliminated the check. This allowed attacker-controlled integer bits to be interpreted as a pointer in optimized code.
2. CVE-2026-79236 — a load-elimination bug in TurboFan. The optimizer retained a pointer to the old property array after the object had migrated and its property storage had been replaced. A subsequent write used the stale pointer, resulting in a controlled memory write.
3. Sandbox escape, issue 546253900 — a vulnerability involving shared WebAssembly memory. The registered backing store did not match the one actually passed to the worker: backing store A, while backing store B was registered globally. When the worker terminated, the cleanup routine failed to remove the reference to its native Isolate from backing store A, leaving a dangling pointer. A subsequent call to memory.grow(0) triggered a native use-after-free outside the V8 sandbox.Attack path
• Both memory-corruption vulnerabilities were initially used to obtain controlled memory access within the pointer-compression cage, which was then used to build the standard
addrof and fakeobj primitives.
• To access mapped memory elsewhere in the sandbox, genuine DataView objects were located and their sandboxed data pointers retargeted.
• After escaping the sandbox, the freed Isolate was reclaimed with a WebSocket message carrying a payload of the appropriate size. The message address was verified before the dangling pointer was dereferenced.
• The exploit then followed a chain of callbacks compatible with control-flow integrity (CFI), pivoted the stack to a ROP chain, and achieved code execution in the renderer process.