Target: Mozilla Firefox
Component: ipc_channel_win.cc (IPC Broker)
Vector: Windows Handle Duplication (Remote)
Firefox relies on the Electrolysis multi-process architecture to separate untrusted web content from system resources.
The vulnerability resides in the IPC Handle Sharing mechanism on Windows. The Broker blindly trusted an integer provided by the compromised Renderer, leading to a catastrophic Sandbox Escape.
The Context: This vulnerability is rated CVSS 10.0. It implies No Authentication, No User Interaction (beyond the initial page load), and results in Full Shell Access on the host machine.
Root Cause: Semantic Confusion regarding Windows Pseudo-Handles.
Windows uses Handles to track resources. A handle is simply an integer index in a kernel table. Process A cannot use Process B’s handles directly; they must be Duplicated by the Kernel.
The flaw exists in the logic that allows the Renderer to ask the Broker to “relay” a handle:
X to me.”DuplicateHandle(BrokerProcess, X, RendererProcess...).X is a valid handle index that belongs to the Renderer.X was a Pseudo-Handle. In Windows, specific negative integers have magical, context-dependent meanings:
-1 = Current Process-2 = Current ThreadThe danger is that -2 means “My Thread.” When the Renderer sends -2, it means “Renderer Thread.” But when the Broker passes -2 to the Kernel, the Kernel interprets it as “Broker Thread.”
The exploit begins with a JavaScript file that triggers a bug in the JIT (Just-In-Time) Compiler.
addrOf) and write fake objects (fakeObj).ArrayBuffer is created to write shellcode into executable WASM memory. Control flow is hijacked. The attacker now has code execution inside the Sandbox.To escape the sandbox, the attacker pivots to the IPC layer. They construct a malicious “Relay Message” destined for the Broker.
-2 (0xFFFFFFFE).The Broker receives the message and calls DuplicateHandle.
BrokerProcess, Handle=-2.-2 coming from the Broker. It resolves this to the Broker’s Main Thread.THREAD_ALL_ACCESS handle to the Broker and sends it back to the Renderer.The compromised Renderer now holds a handle that grants full control over the Parent process.
SuspendThread() to pause the Parent.SetThreadContext() to overwrite the Instruction Pointer (RIP) of the Parent process.ResumeThread().Impact: The Parent process wakes up and immediately executes the attacker’s shellcode. The malware now runs with Medium Integrity, bypassing all sandbox restrictions and granting full access to the operating system.
The remediation requires validating the context of the handle before processing it. The Broker must explicitly reject OS “Magic Numbers.”
Vulnerable Logic (Conceptual):
// VULNERABLE: Blindly passes user input to the Kernel.
HANDLE handle_value = message.ReadInt(); // Attacker sends -2
DuplicateHandle(
GetCurrentProcess(), // Source: Broker
handle_value, // Value: -2 (Interpreted as Broker's Thread)
target_process,
&new_handle,
...
);
Patched Logic:
// PATCHED LOGIC in ipc_channel_win.cc
// Helper to detect magic values (-1, -2, etc.)
// Windows reserves the range [-12, -1] for current context pseudo-handles.
inline bool IsPseudoHandle(HANDLE handle) {
int32_t value = (int32_t)(uintptr_t)handle;
return value >= -12 && value < 0;
}
// In the IPC processing loop:
if (IsPseudoHandle(remote_handle)) {
// SECURITY: Renderer is trying to trick us.
LOG(ERROR) << "Security: Received pseudo-handle.";
return false; // Abort connection
}
// Safe to proceed only if it's a real index.
DuplicateHandle(..., remote_handle, ...);
Context Awareness > Type Safety.
Validating that an input is an “Integer” is insufficient when that integer controls system resources. Magic numbers (like -1 or -2 in Windows) are powerful context-switching mechanisms. Trust boundaries in IPC must enforce that handles are strictly local indices, never interpreted execution contexts. Know your input.