top of page
Search

Intro to Sandbox Escapes: From JS Engine Exploit to Full Privilege Code Execution

  • Writer: ryanpotato2005
    ryanpotato2005
  • Apr 10
  • 5 min read

Browser Sandbox Basics:

Modern browsers use sandboxing to isolate code execution (especially untrusted JS) from the rest of the OS. It uses:

  • User-level privilege reduction (e.g. seccomp, job objects)

  • Filesystem/network restrictions

  • Inter-process communication (IPC) to reach higher-privileged components (render → broker)


Each browser has its own model:

  • Chromium: Multiprocess with sandboxed renderers

  • Firefox: Electrolysis + sandboxing using seccomp

  • Safari: App Sandbox + WebContent process separation


Basic Sandbox Escape Tactics

To escape, you usually need to:

  • Interact with a higher-privileged broker process

  • Trigger a bug in a system API

  • Exploit a kernel vulnerability


Common Vectors:

  • IPC Abuse: Talk to browser processes (like chrome.exe) with malformed or unexpected messages

  • COM Interfaces (on Windows): Abusing IFileOperation, IElevatedFactoryServer, etc.

  • Shared Memory / Race Conditions

  • Windows Named Pipes / DCOM Objects

  • System Calls via JS Native Code / WebAssembly


Nice! We have the basics down but let’s see some real-world examples!


Chains and Sandbox Escapes In The Real World


Let’s break down a known CVE chain:


for example CVE-2022–3075:

This was a juicy sandbox escape bug found in the wild, affecting Chromium-based browsers like Chrome, Edge, Brave, etc. For this Write-Up I don’t plan to heavily dive into Mojo IPC, The Component this CVE is targeting. Instead, I'll be breaking down the concept and showing how this translates into the general idea of browser sandbox escapes.


Exploit Flow


1. The attacker controls JavaScript inside a Chromium tab (renderer process).


2. Using a bug to gain arbitrary memory access in the renderer.


3. Crafts a malicious Mojo message manually (forging structs, interfaces, etc).


4. Sends the forged message to a privileged browser-side Mojo interface.


5. The receiver process mishandles it due to missing validation → logic flaw or memory issue.


6. Attacker gains code execution or privilege escalation outside the renderer sandbox.


Wow, this sounds like a headache, Let’s break it down step by step!


Step 1: The attacker controls JavaScript inside a Chromium tab (renderer process)


An attacker gets code execution in the renderer process by controlling web content. This can be:

  • A malicious website they control (evil.site)

  • A compromised legitimate site (watering hole attack)

  • A malicious ad served via an ad network (malvertising)

  • A phishing link or payload embedded in a PDF/HTML email


Once a target loads the attacker-controlled page in a Chromium-based browser, the attacker gains the ability to run JavaScript in that renderer instance. The initial foothold begins here in the renderer process. This is where JavaScript from web pages is executed in a sandboxed environment, designed to isolate it from the rest of the system. From an attacker’s perspective, this is where payloads live. They craft malicious JavaScript to trigger a vulnerability. This process runs with limited permissions and can’t access local files, devices, or most system APIs. Think of this as being “in the box” — and the goal is to break out of it.


Step 2: Using a bug to gain arbitrary memory access in the renderer


Once inside the renderer, the attacker exploits a JavaScript engine vulnerability (most likely in V8). Let’s assume a Type Confusion bug that allows bypassing type checks, enabling out-of-bounds memory access or object re-interpretation. With this, they gain arbitrary read/write primitives in the renderer’s address space. At this point, the attacker can:


  • Read/write JS object internals

  • Leak pointers

  • Modify function pointers

  • Build WebAssembly shellcode loaders


But still, this is only within the sandboxed process. The next step is to abuse this memory access to craft something dangerous.


Step 3: Crafts a malicious Mojo message manually (forging structs, interfaces, etc)


Chromium uses Mojo IPC to communicate between sandboxed and unsandboxed processes. These communications are based on well-defined interfaces and structures (like protobufs or RPCs). Now that the attacker has memory R/W, they can manually forge a Mojo message in memory—building structures that would normally be generated by legitimate IPC calls.


This includes:

  • Overwriting interface pointers

  • Faking mojo::PendingRemote or mojo::PendingReceiver handles

  • Crafting serialized message layouts directly in memory


The goal is to mimic a valid IPC request, but with malicious or malformed data that will break the recipient’s logic.


Step 4: Sends the forged message to a privileged browser-side Mojo interface


Now comes the key pivot. The attacker sends the crafted message to a high-privileged Mojo interface.


Likely candidates:

  • network::mojom::URLLoaderFactory

  • network::mojom::TrustTokenRequestHandler

  • browser::mojom::FileSystemAccessManager


These interfaces live in browser or utility processes outside the sandbox. They trust input from the renderer — but only under the assumption that Chromium’s internal validation holds. In this case, due to CVE-2022–3075, validation was insufficient. So the malicious message passes through and is processed.


Step 5: Receiver process mishandles it due to missing validation → logic flaw or memory issue


Here’s where the vulnerability bites. The higher-privileged process deserializes and parses the Mojo message. Due to weak or missing input validation, it misinterprets the data. This leads to:

  • A logic flaw: an attacker performs an unauthorized operation (e.g., arbitrary file read/write, bypassing security checks)

  • Or memory corruption: out-of-bounds access, use-after-free, or dangling pointer dereference — leading to RCE in the browser process


The attacker now has native code execution in a process with more privileges!


Step 6: Attacker gains code execution or privilege escalation outside the renderer sandbox


With execution outside the sandbox, the attacker can:

  • Read/write local files

  • Launch child processes

  • Communicate with OS-level services

  • Capture keystrokes or screen content (depending on privileges)


If the exploit chain includes another step (e.g., kernel exploit), they can even escalate to SYSTEM/root! At this point, the sandbox is broken, game over.


Now we have a general idea of browser sandbox escapes!


How Is This Useful?


A successful sandbox escape lets an attacker pivot from a low-privileged, constrained environment to a much more dangerous one! Typically a browser or utility process that:

  • Has broader file system access

  • Can spawn processes

  • Accesses OS-level APIs

  • Has inter-process communication (IPC) rights

  • May not be monitored as closely as the renderer


This unlocks a range of real-world impacts depending on the attacker’s goal.


What It Can Lead To


Once outside the sandbox, attackers can:

  • Exfiltrate sensitive files (cookies, localStorage, passwords)

  • Interact with the OS via APIs (clipboard, screen capture, mic/cam access in some cases)

  • Abuse credentials (SSO tokens, OAuth sessions, WebAuthn)

  • Move laterally by injecting into other processes or establishing persistence

  • Chain into kernel exploits for full privilege escalation


In targeted attacks, sandbox escapes are essential. They’re often paired with zero-day exploits in V8 or Blink to build full exploit chains — like the ones seen in:

  • NSO’s Pegasus spyware

  • Pwn2Own browser chains

  • APT attacks targeting journalists or dissidents


Recap & Final Thoughts


This write-up was meant to be a brief overview, NOT a full deep dive into how sandbox escapes work and why they matter in browser exploitation. The goal was to break down the core concepts, not to walk through a full 0-day chain or reproduction of a CVE in the wild. Sandbox escapes aren’t typically flashy or directly usable for things like initial access or payload delivery. You can’t just “run a sandbox escape” in isolation and get code execution out of nowhere.


They’re a critical part of any serious browser exploit chain!


You might have:

  • A V8 or WebAssembly exploit giving you JS engine RCE

  • A Mojo abuse or IPC logic flaw breaking the sandbox

  • A kernel LPE chaining you to SYSTEM


That middle step? The sandbox escape. It’s the bridge from “browser bug” to “system compromise.”


So while this was just a surface-level look, hopefully, it helped clarify why sandbox escapes are so important, how they’re used in real-world attacks, and how attackers typically pull them off after getting a foothold in the renderer.


 
 
 

留言


bottom of page