Skip to content

Build1 publisher2 min readPublished

Chrome adds V8's in-process sandbox to its bug bounty before calling it a strong boundary

V8 says 60% of the Chrome exploits caught in the wild between 2021 and 2023 started in its own code, and that the logic bugs behind them are out of reach of both Rust and memory tagging, so the work went into containment.

The Engineer · Build desk

Illustration accompanying Chrome adds V8's in-process sandbox to its bug bounty before calling it a strong boundary

What happened

  • V8's in-process sandbox is no longer classed as an experimental security feature after almost three years and hundreds of CLs, and it is now included in Chrome's Vulnerability Reward Program.
  • V8 says every Chrome exploit caught in the wild from 2021 to 2023 began with memory corruption in a renderer process, and that 60% of those bugs were in V8 itself.
  • Those V8 bugs are rarely use-after-frees or out-of-bounds accesses, according to the post, but subtle logic issues that an attacker then uses to corrupt memory.
  • V8 says neither a rewrite in a memory safe language such as Rust nor hardware features such as memory tagging address that class of bug, and positions the sandbox as containment within the host process.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • exposure VRP inclusion puts a price on sandbox escapes, so the techniques that break the boundary now come from researchers outside the team who have a reason to file rather than keep them.
  • constraint The guarantee stops at the host process, so anyone embedding V8 still has to plan for a corrupted V8 heap and ask what else lives in that address space.
  • decision Security teams have to decide whether "no longer experimental" is enough to depend on when the maintainers themselves say the boundary is not yet strong.
  • precedent If a bug class survives both language migration and hardware tagging, containment becomes the default answer for JIT engines, and future memory-safety hardware will not retire the work.

The bug in V8's own example is four lines of C++. A loop reads `buffer_[index]`, converts it with `ToNumber`, and, when the value divides by 15, writes `JSString("fizzbuzz")` back into the same slot [10]. `ToNumber` can invoke user-defined JavaScript callbacks [11]. The proof of concept in the post gives an object a `Symbol.toPrimitive` method that sets `array.length = 1` and returns 15, pushes that object onto an array of 100, and calls `fizzbuzz()`; the callback fires at index 100, the backing buffer is reallocated, and the write on the next line goes out of bounds [12]. V8 says this specific pattern is mostly extinct now, seen off by better fuzzers, developer awareness and researcher attention [16].

The reason it is in the post anyway is the second place it can live. The same mistake appears in hand-written runtime code and in machine code an optimizing JIT compiler generates at runtime [13]. In the first case a human decides the bounds check is unnecessary because that index was just accessed. In the second, a pass such as redundancy elimination or bounds-check elimination reaches the same conclusion, because it does not model the side effects of `ToNumber()` [14]. V8's assessment is that a memory-safe language would likely prevent the bug in the hand-written interpreter code and would not prevent it in the JIT [15]. Of the two paths, a language migration covers one [17].

So the claim made for the sandbox is a narrow one. It is lightweight and in-process, and what it does is prevent memory corruption in V8 from spreading within the host process [1][9]. That addresses the second stage of an exploit chain and not the first. V8 says a number of issues remain before the sandbox becomes a strong security boundary, and describes Chrome 123 as a sort of "beta" release for it [3][4], which is an unusual thing to put in writing about a security feature and a useful one. Adding it to the Vulnerability Reward Program is how the remaining issues get found by people who do not work on it [2].

The 60% is a count of exploits caught in the wild against Chrome renderer processes over 2021 to 2023 [5][6]. For that number to describe your deployment, your V8 has to be taking attacker-controlled JavaScript, and your process has to hold roughly what a renderer holds. An embedder that only ever runs its own scripts is not in that population. An embedder that runs untrusted JavaScript in a process holding filesystem or network credentials is in a worse position than a renderer, because the guarantee on offer ends at the host process [9].

What to watch

  • The specific issues V8 says stand between the sandbox and a strong security boundary, and whether they are published as they close.
  • The first VRP-rewarded report against the sandbox, and whether it comes through the interpreter path or the JIT path.
  • Whether V8 embedders outside Chrome turn the sandbox on now that it is out of experimental status.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories