CVE-2026-3909 & CVE-2026-3910 Technical Deep Dive into Chrome's Dual Zero-Day Exploit Chain
Executive Summary
On March 13, 2026, Google issued an out-of-band emergency security update for Chrome 146, patching two actively exploited zero-day vulnerabilities — CVE-2026-3909 (Skia out-of-bounds write) and CVE-2026-3910 (V8 inappropriate implementation). Both vulnerabilities were reported by Google’s internal team on March 10, 2026, with patches shipped within approximately two days — an unusually fast turnaround that signals confirmed, targeted exploitation in the wild.
What makes this incident particularly dangerous is that these two vulnerabilities are not independent bugs. They form a chained exploit: CVE-2026-3909 achieves memory corruption and initial code execution within the renderer sandbox, while CVE-2026-3910 provides the sandbox escape needed to compromise the host OS. Together, they deliver full Remote Code Execution (RCE) via a single malicious webpage — with zero interaction required from the victim beyond loading the URL.
CISA added both to its Known Exploited Vulnerabilities (KEV) Catalog, mandating U.S. Federal Civilian Executive Branch agencies to apply patches by March 27, 2026.
CVE Summary
| Field | CVE-2026-3909 | CVE-2026-3910 |
|---|---|---|
| Component | Skia (2D graphics library) | V8 JavaScript Engine |
| Type | Out-of-bounds write | Inappropriate implementation |
| CVSS Score | 8.8 (High) | 8.8 (High) / 9.8 (Critical, CVSS 4.0) |
| Attack Vector | Remote (crafted HTML page) | Remote (crafted HTML page) |
| Attack Complexity | Low | Low |
| Privileges Required | None | None |
| User Interaction | Required (visit page) | Required (visit page) |
| Scope | Changed (sandbox boundary) | Changed (full sandbox escape) |
| Exploitation | Active in the wild | Active in the wild |
| CISA KEV | Yes | Yes |
| Patch Version | Chrome 146.0.7680.75/76 | Chrome 146.0.7680.75/76 |
Background: Chrome’s Security Architecture
To understand these vulnerabilities, we must first understand Chrome’s defense-in-depth model:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────────────────┐
│ BROWSER PROCESS │
│ (high-privilege, manages tabs, handles UI, network I/O) │
└───────────────────────────┬─────────────────────────────────┘
│ IPC (Mojo)
┌───────────────────────────▼─────────────────────────────────┐
│ RENDERER PROCESS │
│ (low-privilege sandbox per tab) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ V8 JAVASCRIPT ENGINE │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ V8 SANDBOX │ │ │
│ │ │ (isolates JS heap from renderer process) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Skia (graphics rendering — runs in renderer process) │
└─────────────────────────────────────────────────────────────┘
Three layers of isolation protect the OS:
- OS Process Sandbox — renderer runs as a low-privilege process, cannot directly call OS APIs
- V8 Sandbox — isolates the JavaScript heap from the rest of the renderer process memory
- Site Isolation — each origin runs in its own renderer process
The exploit chain targeted layers 2 and 3 simultaneously.
CVE-2026-3909: Out-of-Bounds Write in Skia
What is Skia?
Skia is an open-source 2D graphics library that serves as the rendering engine for Chrome (and Android, Flutter, Firefox via SkiaSharp, and many other products). It handles:
- Rendering HTML canvas elements
- Processing SVG paths and filters
- Rasterizing fonts and images
- GPU-accelerated compositing via OpenGL/Vulkan/Metal backends
Because Skia sits at the intersection of the web content and the GPU/CPU rendering pipeline, it processes attacker-controlled data (SVG markup, canvas operations, CSS filters) with high complexity and relatively low security scrutiny historically.
The Vulnerability: Out-of-Bounds Write
An out-of-bounds write (OOB-W) occurs when software writes data to a memory address beyond the end of an allocated buffer. In Skia’s case, the bug resided in the bounds-checking logic of its memory management routines during graphics processing.
Root cause (conceptual):
1
2
3
4
5
6
7
8
9
10
// Simplified vulnerable pattern — NOT actual Skia source
void SkiaRenderPath(SkPath* path, uint8_t* buffer, size_t buffer_size) {
size_t required = ComputeRequiredBytes(path);
// BUG: required can exceed buffer_size under certain path configurations
// Bounds check is insufficient or absent for certain edge cases
for (size_t i = 0; i < required; i++) {
buffer[i] = ProcessPathSegment(path, i); // OOB write when i >= buffer_size
}
}
The miscalculation could be triggered by:
- Specially crafted SVG path elements with extreme coordinate values or complex curve definitions
- Malformed HTML5 Canvas operations with unusual transformation matrices
- CSS filter functions that invoke Skia’s blur/shadow rendering pipelines with edge-case parameters
Memory Corruption Impact
When an OOB write occurs in the renderer process, an attacker can:
- Corrupt adjacent heap objects — overwrite metadata of objects allocated after the Skia buffer
- Overwrite vtable pointers — if a C++ object’s virtual function table pointer is adjacent, replacing it enables control flow hijacking
- Achieve controlled write primitive — with careful heap grooming, write specific bytes to specific offsets, enabling more precise exploitation
1
2
3
4
5
6
7
8
9
10
Heap Layout (attacker-groomed):
[ Skia Buffer ] [ Target Object ] [ Other objects... ]
0x1000 0x1100 0x1200
After OOB write:
[ Skia Buffer ] [CORRUPTED VTABLE ] [ Other objects... ]
0x1000 ↑
Attacker controls what's written here
→ redirect virtual function call to shellcode
Triggering via a Webpage
The attack vector is straightforward:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1">
<!-- Crafted path data designed to trigger the OOB write in Skia's path rasterizer -->
<path d="M 0 0 [maliciously crafted coordinate sequence...]"
style="filter: blur(0.001px)"/>
</svg>
<canvas id="c"></canvas>
<script>
// Canvas operations can also trigger the Skia rendering path
const ctx = document.getElementById('c').getContext('2d');
// ... additional trigger conditions
</script>
</body>
</html>
At this stage, the attacker has achieved arbitrary code execution within the renderer sandbox — but they’re still contained. This is where CVE-2026-3910 enters.
CVE-2026-3910: Inappropriate Implementation in V8 (Sandbox Escape)
What is the V8 Sandbox?
The V8 Sandbox is a security feature introduced by Google specifically to mitigate the impact of V8 memory corruption bugs. Its core principle:
Even if an attacker achieves arbitrary read/write within the V8 JavaScript heap, the damage should be contained to within the V8 sandbox region — they should not be able to reach other parts of the process memory.
V8 achieves this through pointer sandboxing: instead of storing raw 64-bit pointers, V8 objects store compressed 32-bit offsets relative to a fixed sandbox base address. When V8 needs to access an external resource (e.g., array buffers, typed arrays, external C++ objects), it uses a special External Pointer Table (EPT) — an indirection table where sandboxed code holds an index into the table, not a raw pointer.
1
2
3
4
5
6
7
8
9
10
11
12
13
V8 Sandbox Memory Layout:
[Sandbox Base]
├── [JS Heap] ← V8 objects live here
├── [External Pointer Table (EPT)] ← maps indices → real pointers
│ Index 0 → 0x7fff12340000 (real ArrayBuffer backing store)
│ Index 1 → 0x7fff56780000 (real C++ object)
│ Index 2 → 0x7fff89AB0000 (real WASM memory)
└── [Code Cage] ← JIT-compiled code lives here
Sandboxed code accesses external resources by index:
load_external_pointer(object.external_ptr_idx)
→ EPT[external_ptr_idx] → real address
This design means a compromised JS heap should not be able to forge arbitrary pointers to OS memory.
The Vulnerability: Logic Error in JIT External Pointer Handling
CVE-2026-3910 is described as an “inappropriate implementation” — a category that typically means a logical error in security-critical code, as opposed to a classic memory safety bug.
The specific flaw was a logic error in how V8 handles External Pointers during Just-In-Time (JIT) compilation. During JIT optimization, V8 generates native machine code for hot JavaScript functions. The bug allowed certain JIT-compiled paths to access External Pointer entries in a way that bypassed the EPT’s integrity checks — specifically, by corrupting the EPT entries themselves to point to arbitrary addresses outside the sandbox.
Conceptual exploit primitive:
1
2
3
4
5
6
7
8
9
10
11
12
13
// Conceptual — simplified representation of the class of bug
// NOT actual exploit code
// After achieving OOB write via CVE-2026-3909 (step 1):
// Attacker has corrupted a V8 object's external_ptr_idx field
// The JIT-compiled version of this innocent-looking code
// will now dereference the corrupted EPT entry:
let ab = new ArrayBuffer(0x1000);
let view = new DataView(ab);
// With corrupted EPT entry, 'ab' now backs to attacker-controlled address
// outside the V8 sandbox:
view.setBigUint64(0, 0x41414141n); // Write to arbitrary OS memory
Once the attacker can write to arbitrary process memory (outside the V8 sandbox), they can:
- Overwrite function pointers in the renderer process
- Inject shellcode into executable memory regions
- Call OS APIs directly, bypassing the process sandbox via compromised IPC handlers
The Full Exploit Chain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Step 1: Lure victim to malicious webpage
↓
Step 2: JavaScript executes → crafted SVG/Canvas triggers Skia OOB write
↓ CVE-2026-3909
Step 3: Memory corruption in renderer process heap
→ overwrite adjacent V8 heap object metadata
↓
Step 4: V8 object now has corrupted external_ptr_idx or object layout
↓
Step 5: JIT-compiled JS code accesses corrupted EPT entry
↓ CVE-2026-3910
Step 6: Arbitrary read/write to full process memory (V8 sandbox escape)
↓
Step 7: Overwrite renderer process function pointers / inject shellcode
↓
Step 8: Execute OS-level code — exfiltrate data, drop malware, persist
↓
[Full System Compromise]
Attack trigger: Zero clicks after page load. The browser visits the URL, Skia renders the page, the exploit executes — all before the user sees anything unusual.
Heap Grooming: The Hidden Craft Behind the Exploit
Raw memory bugs rarely translate to reliable exploits without heap grooming — a technique to manipulate the memory allocator into placing attacker-controlled objects in predictable adjacent locations.
For CVE-2026-3909, an attacker would likely:
- Spray the heap — allocate many JavaScript objects (ArrayBuffers, strings, typed arrays) of specific sizes to fill memory holes and establish a predictable heap layout
- Create an allocation “hole” — free some objects to create a gap of exactly the right size for Skia’s buffer
- Trigger Skia allocation — Skia allocates its buffer precisely into that hole
- Allocate the target object — immediately after, allocate the V8 object whose EPT index field they want to corrupt
- Trigger the OOB write — Skia writes out-of-bounds into the target V8 object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Conceptual heap grooming pattern:
function groomHeap() {
let spray = [];
// Allocate many objects of size 0x100 to fill heap regions
for (let i = 0; i < 0x1000; i++) {
spray.push(new ArrayBuffer(0x100));
}
// Free every other one to create predictable holes
for (let i = 0; i < spray.length; i += 2) {
spray[i] = null;
}
// Force GC to process frees
// [Trigger SVG rendering to allocate Skia buffer into hole]
// [Allocate target V8 object after the hole]
}
This grooming phase is typically the most complex part of exploit development — and its reliability determines whether an exploit is weaponizable at scale.
Attack Scenarios Observed in the Wild
Based on the CVSS profile (no privileges required, low complexity, network-delivered) and Google TAG’s confirmation of targeted exploitation, likely attack scenarios include:
1. Watering Hole Attack
Attackers compromise a legitimate high-value website (government portal, financial institution, industry forum) and inject the malicious page. Any visitor using unpatched Chrome is silently compromised.
2. Phishing Link
A single link sent via email, messaging app, or social media. Victim clicks → browser loads page → exploit executes. No further interaction needed.
3. Malicious Ad (Malvertising)
The exploit is delivered via a compromised ad network. Any site displaying the malicious ad becomes an attack vector, even if the site itself is legitimate and trusted.
4. Compromised iframe
A trusted site embeds a third-party iframe (analytics, widgets, comment systems). If that third party is compromised, the exploit runs in the context of the trusted site’s renderer.
Detection Indicators
Since public technical details and PoC are still restricted by Google, signature-based detection is limited. Focus on behavioral indicators:
Network-Level (Blue Team):
- Unusual DNS queries or HTTP connections from
chrome.exe/chromiumprocesses to unfamiliar C2 infrastructure immediately after user browses a specific URL - Renderer process spawning child processes unexpectedly
- Memory-resident processes with no disk artifact (fileless malware dropped post-exploit)
Host-Level:
- Chrome renderer process (
chrome.exe --type=renderer) making unusual system calls (file writes, network connections) - Anomalous process creation from renderer PID
- Suspicious
chrome_*named pipes or Mojo IPC traffic
Browser Telemetry:
- Chrome crash reports (
crashpad) immediately before suspicious behavior - Sudden DOM mutation events followed by renderer process restart
Affected Products
CVE-2026-3909 and CVE-2026-3910 affect all Chromium-based browsers prior to the fix. This includes:
| Browser | Affected | Notes |
|---|---|---|
| Google Chrome | ✅ Yes | Primary target, patched in 146.0.7680.75/76 |
| Microsoft Edge | ✅ Yes | Chromium-based, patch expected |
| Brave | ✅ Yes | Chromium-based |
| Opera | ✅ Yes | Chromium-based |
| Vivaldi | ✅ Yes | Chromium-based |
| Samsung Internet | ✅ Yes | Chromium-based (Android) |
| Firefox | ❌ No | Uses SpiderMonkey (not V8) and Moz2D (not Skia) |
| Safari | ❌ No | Uses JavaScriptCore and CoreGraphics |
Skia is also used in Android’s graphics stack — related bugs (e.g., CVE-2025-32318) have appeared in that context independently.
Remediation and Mitigation
Immediate Actions (Priority 1)
1. Update Chrome Now
1
2
3
4
5
Windows / macOS: Chrome 146.0.7680.76
Linux: Chrome 146.0.7680.75
Android: Chrome 146.0.76380.115
Check version: chrome://settings/help
2. Force restart for enterprise fleets
1
2
3
4
5
6
# Windows — kill and restart via Group Policy or endpoint management
taskkill /F /IM chrome.exe /T
Start-Process "chrome.exe"
# Linux
pkill -f chrome && google-chrome &
3. Update all Chromium-based browsers in your environment — Edge, Brave, Opera, etc.
Compensating Controls (if patching is delayed)
Disable JavaScript — breaks the V8 exploit stage, but severely impacts usability:
chrome://settings/content/javascript→ Block
Enable Enhanced Safe Browsing:
chrome://settings/security→ Enhanced protection
Deploy browser isolation (Zero Trust Network Access):
- Remote Browser Isolation (RBI) products render pages in an isolated cloud VM — even successful exploitation only compromises the cloud container, not the endpoint
Web Application Firewall rules:
- Block or alert on responses containing suspicious SVG path patterns with extreme coordinate values
- Block responses with unusual canvas API call sequences (limited effectiveness, attacker can obfuscate)
Broader Context: The Skia & V8 Pattern
CVE-2026-3909 is not a one-off. The Skia library has been a recurring exploit target:
| CVE | Year | Component | Type |
|---|---|---|---|
| CVE-2024-7966 | 2024 | Skia | OOB read |
| CVE-2025-32318 | 2025 | Skia (Android) | Heap buffer overflow |
| CVE-2026-3909 | 2026 | Skia | OOB write |
Similarly, V8 sandbox escapes have become an annual occurrence:
| CVE | Year | Type |
|---|---|---|
| CVE-2025-6554 | June 2025 | Type confusion → arb R/W |
| CVE-2025-10585 | Sep 2025 | Type confusion → RCE |
| CVE-2025-13223 | Nov 2025 | Type confusion |
| CVE-2026-3910 | Mar 2026 | EPT logic error → sandbox escape |
This pattern has two implications:
Skia’s attack surface is structurally underprotected relative to its exposure to attacker-controlled data. Memory-safe rewrites (e.g., Rust) of critical Skia paths may become necessary long-term.
The V8 Sandbox remains an incomplete protection boundary. Each generation of V8 Sandbox bypasses reveals a new logical boundary that must be hardened. Google’s own research acknowledges this is an ongoing arms race.
There is also emerging evidence, noted by Google TAG, that AI-powered fuzzing is accelerating how quickly threat actors find logical errors in complex codebases like V8 — collapsing the time between vulnerability discovery and weaponized exploitation.
Conclusion
CVE-2026-3909 and CVE-2026-3910 represent the current state of the art in browser exploitation: a precisely coordinated two-stage chain that leverages a low-level rendering library vulnerability to corrupt the JavaScript engine’s security boundary, achieving full remote code execution with no prerequisites other than a user visiting a URL.
The speed of exploitation (same-day in targeted campaigns), the breadth of affected platforms (all Chromium-based browsers across all OS), and the delivery vector (any webpage, including trusted sites via iframes and malvertising) make this a high-impact incident.
For defenders, the path is clear: patch immediately, monitor for post-exploitation behavioral anomalies, and invest in browser isolation for high-risk users.
For the industry, the broader lesson is equally clear: the browser is now the primary operating system of the enterprise, and it must be treated with the same rigor as OS-level security.
References
- NVD — CVE-2026-3909
- NVD — CVE-2026-3910
- Google Chrome Releases Blog
- CISA Known Exploited Vulnerabilities Catalog
- Malwarebytes — Google patches two Chrome zero-days
- The Hacker News — Chrome Zero-Day Analysis
- Bleeping Computer — Chrome Zero-Days
- V8 Sandbox Design Documentation
- Skia Source Repository
- Forbes — Google Zero-Day Alert for 3.5 Billion Chrome Users
This post is intended for security researchers, incident responders, and enterprise security teams. Exploit primitives described here are based on publicly available vulnerability class analysis and do not constitute or include functional exploit code.