Feb 15, 2026·6 min read·43 visits
Critical Race Condition in Chrome's V8 engine involving `ReadableStream` and `SharedArrayBuffer`. Allows remote attackers to bypass the V8 Sandbox and achieve RCE via a crafted HTML page. Patched in Chrome 139.0.7258.127.
A high-severity race condition in Google Chrome's V8 JavaScript engine allows attackers to bypass the V8 Sandbox and execute arbitrary code. By exploiting the interaction between `ReadableStream` consumers and `SharedArrayBuffer`, attackers can corrupt heap memory via a data race, effectively turning a browser tab into a foothold for system compromise. This vulnerability was successfully demonstrated in v8CTF by researcher Seunghyun Lee.
JavaScript is famously single-threaded. It’s the one thing that keeps browser exploit development somewhat sane—you generally know the state of the world when your code executes. But then came SharedArrayBuffer (SAB). SABs are the chaotic evil of the JavaScript world because they allow true concurrency. They let the main thread and a Web Worker shout at the same chunk of memory simultaneously.
Now, enter ReadableStream. Streams are designed to pipe data efficiently, often optimized in C++ within the V8 engine. V8 developers assume that when they are reading a buffer, the floor won't drop out from under them. They assume stability.
CVE-2025-8880 is what happens when that assumption meets reality. It’s a race condition where the engine tries to consume a stream backed by shared memory, but a concurrent thread modifies that memory state mid-consumption. This isn't just a crash; it's a high-precision tool to break the V8 Sandbox, the security boundary Google built specifically to stop us from doing exactly this.
The vulnerability (CWE-362) lies in the synchronization—or lack thereof—between the ReadableStream implementation and the underlying buffer storage when that storage is a SharedArrayBuffer.
In a typical Time-of-Check to Time-of-Use (TOCTOU) scenario, the engine checks the length of the data to ensure it's safe to read. It says, "Okay, this buffer is 1024 bytes. I will read 1024 bytes." It then proceeds to the read operation.
However, because the backing store is shared, a malicious Web Worker running in the background can modify the buffer or detach it in the nanoseconds between the check and the use. If the worker shrinks the buffer or creates an inconsistent state exactly when the stream consumer (the C++ side) is processing it, V8 ends up reading or writing to memory that no longer belongs to that buffer. This results in memory corruption on the V8 heap.
To understand the fix, we have to look at what was missing. The patch series (CL 6787532, 6811146) introduces memory barriers and explicit locking mechanisms during stream consumption.
The vulnerable logic looked something like this (pseudocode representation of V8 internal logic):
// VULNERABLE LOGIC
void ReadableStream::PullFromSource() {
// 1. Get pointer to buffer
void* data = buffer->data();
// 2. Get length
size_t len = buffer->byte_length();
// ... minimal context switch ...
// 3. Read data assuming 'len' is valid for 'data'
memcpy(destination, data, len);
}If a Web Worker thread resizes or detaches the buffer between step 2 and step 3, len is now stale, and memcpy goes out of bounds. The fix involves ensuring that the buffer cannot be modified while the stream is locking it for a read operation, effectively serializing the access.
> [!NOTE]
> The patch introduces v8::internal::SharedMutex usage in streams.cc to ensure that ReadableStream operations hold a read lock on the backing store, preventing the SAB from mutating under its feet.
This is where Seunghyun Lee (@0x10n) earned his paycheck. Exploiting a race condition in a browser is technically demanding because you have to win the race consistently. The exploit strategy likely involves the following chain:
SharedArrayBuffer and wrap it in a ReadableStream.Response object or a TextDecoder) that will read from the stream.By carefully arranging the heap (Heap Feng Shui), the attacker places a victim object (like an Array or an Object) immediately after the SAB. The out-of-bounds write overwrites the map or elements pointer of the victim object.
Once you have corrupted an object's pointer, you can create a "fake object" primitive. In modern V8, this allows you to read/write anywhere inside the V8 Sandbox. However, because this specific bug corrupts the underlying backing store management, it provides a bridge to write outside the sandbox, leading to full RCE.
Why is this critical? Modern browsers use a technique called the "V8 Sandbox" to contain exploits. Even if you get code execution in JavaScript, you are supposed to be trapped in a 4GB virtual address space, unable to touch the rest of the renderer process.
CVE-2025-8880 is a Sandbox Escape. It breaks the containment vessel. An attacker who exploits this can:
The fact that this was demonstrated in v8CTF proves it is weaponizable. It's not theoretical.
Google patched this in Chrome version 139.0.7258.127. If you are running anything older, your browser is a ticking time bomb waiting for a malicious ad or a compromised website.
Remediation Steps:
chrome://settings/help and ensure you are on the latest stable channel.SharedArrayBuffer usage via the SharedArrayBufferEnabled enterprise policy, though this will break sites like Google Earth, Figma, and heavy web games.For Developers:
This is a stark reminder that SharedArrayBuffer introduces hard concurrency problems into a language that wasn't originally designed for them. If you are writing native modules or working on JS engines, never trust the length of a shared buffer to stay constant across a function call.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Google Chrome Google | < 139.0.7258.127 | 139.0.7258.127 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-362 (Race Condition) |
| CVSS v3.1 | 8.8 (High) |
| Attack Vector | Network (Web) |
| Privileges Required | None |
| User Interaction | Required (Visit Page) |
| Impact | Remote Code Execution / Sandbox Escape |
Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.
A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.
OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.
An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.
A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.
An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.