The Fatal Character: How a Single Typo Triggered an RCE Vulnerability in Firefox

Mountain View/London – In the high-stakes world of software engineering, the difference between a secure system and a total compromise can be a single keystroke. Security researcher “Erge” has documented how a simple typo in SpiderMonkey-Firefox’s JavaScript engine-created a critical Remote Code Execution (RCE) vulnerability, allowing attackers to execute arbitrary code within the browser’s renderer process.

The flaw was discovered in February 2026 while the researcher was auditing the Firefox source code for an upcoming “Capture The Flag” (CTF) competition. The bug resided in the WebAssembly (Wasm) component, specifically within the memory management for Garbage-Collected (GC) arrays.

The “Guilty Commit”: An & Instead of a |

The root cause of the vulnerability traces back to a refactoring of Wasm array metadata. In the file js/src/wasm/WasmGcObject.cpp, a classic logical error occurred during bitwise manipulation:

The flawed code snippet:

C++

// Intended to use a bitwise OR (|) to set a flag.
oolHeaderOld->word = uintptr_t(oolHeaderNew) & 1; // The error: '&' instead of '|'

As noted in the technical write-up, the code was intended to store a “forwarding pointer” by setting its least significant bit (LSB) to 1. However, because pointers in modern 64-bit systems are 8-byte aligned, their LSB is always 0. Performing a bitwise AND (&) with 1 effectively forced the stored value to 0 every time.

Inline vs. Out-of-Line: A Memory Misunderstanding

To understand the severity, one must look at how Firefox stores Wasm arrays. The engine uses two distinct layouts:

  1. Inline (IL): Data is stored directly within the object (optimized for small arrays).
  2. Out-of-Line (OOL): The object contains a pointer to a separate memory block (used for larger arrays).

Because of the typo, the engine failed to correctly tag moved OOL arrays. When the system checked the header, the missing bit led it to believe a large, relocated array was still an “Inline” array.

From Logic Error to Full System Takeover

The researcher demonstrated that this confusion leads to a Use-After-Free (UAF) condition. When the Garbage Collector (GC) moves an array, it frees the old memory. However, SpiderMonkey’s JIT compiler (Ion), misled by the faulty header, continues to access the old, now-freed memory address.

By utilizing “heap spraying”-a technique where the memory is flooded with attacker-controlled data-Erge was able to:

  • Bypass ASLR: Leak memory addresses to circumvent operating system protections.
  • Arbitrary Write: Gain the ability to write data to any location in the memory.
  • Achieve RCE: Hijack the instruction pointer (RIP) to execute a shell command (/bin/sh).

Rapid Response from Mozilla

Fortunately, the vulnerability was caught very early in its lifecycle. The bug was introduced on January 19, 2026, and only ever reached the Firefox 149 Nightly builds. It never made it into a stable, public release.

Disclosure Timeline:

  • Jan 19, 2026: Bug introduced via a refactoring commit.
  • Feb 03, 2026: Erge and another anonymous researcher independently report the issue.
  • Feb 09, 2026: Mozilla officially fixes the vulnerability.
  • Feb 11, 2026: A security bounty is awarded and split between the two reporters.

While the quick turnaround by the Firefox security team prevented any widespread risk to users, the case serves as a stark reminder of how fragile modern high-performance software can be. A single accidental character was all it took to dismantle the browser’s security architecture.

Source: https://kqx.io/post/firefox0day/

Leave a Comment

Your email address will not be published. Required fields are marked *

Mastodon
Scroll to Top