A 256-megabyte JavaScript bomb that tricks Firefox into confusing its own stack frames, like mislabeling every box in a warehouse so the forklift grabs hazmat instead of paperclips
CVE-2026-8389 is a type confusion in Mozilla Firefox's SpiderMonkey BaselineJIT compiler. The RetAddrEntry structure stores bytecode offsets (pcOffset_) in a 28-bit bitfield, capped by BaselineMaxScriptLength = 0x0fffffff. The main-thread compilation path enforces this limit, but the eager off-thread baseline-compile path does not. An attacker who serves JavaScript whose bytecode exceeds 256 MB triggers silent truncation of the pcOffset via bitwise masking. During exception unwinding, SpiderMonkey retrieves the wrong bytecode program counter, performs incorrect try-note matching, and reads a stack slot that is not a JSObject* as if it were one — dispatching through a corrupted vtable for a clean type confusion. All Firefox versions prior to 150.0.3 are affected. Firefox ESR 115.x and 140.x are not listed in MFSA2026-45 and appear unaffected, as the eager off-thread baseline-compile path is a mainline-only feature.
Mozilla rates this HIGH at 8.8, and the raw CVSS vector is fair for what the bug achieves (network-reachable, no auth, full C/I/A). However, the vendor score overweights the theoretical ceiling and underweights three real-world friction points: (1) Firefox's desktop market share is ~7.5%, and enterprise deployments overwhelmingly use ESR, which is not affected; (2) the exploit payload must generate >256 MB of bytecode, causing visible browser freeze and high memory pressure; (3) successful exploitation lands inside Firefox's content-process sandbox — full host compromise requires chaining with a separate sandbox escape like CVE-2026-8401. A secondary CVSS assessment on vulnerability.circl.lu scored this at 7.5 with AC:H, which better reflects the real attack complexity. noisgate concurs with that assessment.
5 steps from start to impact.
Lure victim to attacker-controlled page
- Victim uses Firefox mainline < 150.0.3
- Victim navigates to attacker-controlled content
- Firefox desktop market share is ~7.5%; enterprise ESR is unaffected
- Email gateways and URL filtering intercept most phishing lures
- Content Security Policy headers on legitimate sites limit injection
Generate >256 MB bytecode to trigger eager off-thread compile
pcOffset_ bitfield limit (256 MB). This triggers the eager off-thread baseline compilation path, which lacks the BaselineMaxScriptLength guard present on the main-thread path. The browser will freeze noticeably during compilation, consuming 1-2 GB of RAM. The crixpwn PoC (poc-win-rce.html) demonstrates this with a primer script that inflates bytecode via repeated function generation.- JavaScript execution enabled in the browser
- Sufficient system RAM (~2 GB free) to compile the oversized script
- Visible browser freeze of several seconds alerts the user
- Memory-constrained hosts may OOM-kill the content process before compilation completes
- Script-blocking extensions (uBlock Origin, NoScript) prevent execution entirely
pcOffset truncation corrupts exception unwinding
RetAddrEntry::pcOffset_ is silently truncated by the 28-bit bitfield store (pcOffset & 0x0FFFFFFF). When the attacker triggers an exception in the compiled code, SpiderMonkey's unwinder retrieves the wrong bytecode pc and performs incorrect try-note matching, reading a stack slot that contains a non-object value.- Eager off-thread baseline compilation completed successfully
- Exception path triggered in the compiled function
- The truncated offset must land on a valid-but-wrong bytecode instruction — misalignment causes a crash rather than exploitation
Type confusion yields controlled code execution
JSObject* and dispatched through its vtable. The attacker shapes heap layout so the fake vtable pointer redirects control flow to attacker-controlled data, achieving arbitrary code execution within the Firefox content process. The crixpwn PoC demonstrates this on Windows with a working RCE payload.- Heap must be groomed to place controlled data at the expected vtable offset
- Target architecture matches PoC (Windows x64 demonstrated)
- Firefox content process runs inside a sandbox (Win32k lockdown, restricted token on Windows; seccomp-bpf on Linux)
- ASLR and CFI mitigations require additional info-leak and bypass steps
Sandbox escape required for full host compromise
- A working sandbox escape exploit (e.g., CVE-2026-8401) is chained
- Or: sandbox is administratively disabled (rare in enterprise)
- CVE-2026-8401 is also patched in 150.0.3 — patching one fixes both
- Sandbox escape exploits are significantly harder to develop and more brittle across OS versions
- No public PoC for CVE-2026-8401 sandbox escape has been observed
javascript.options.baselinejit.threshold to -1 and javascript.options.ion to false via enterprise Group Policy (policies.json or Windows GPO ADMX). This eliminates the BaselineJIT compilation path entirely, making the pcOffset truncation unreachable. Deploy within 30 days per the noisgate mitigation SLA for HIGH. Performance impact is noticeable (~10-30% slower JS execution) but acceptable as a temporary measure.D4F940AB-401B-4EFC-AADC-AD5F3C50688A — Block all Office applications from creating child processes; configure browser-specific rules via Defender for Endpoint). This breaks the post-exploitation chain by preventing the sandboxed content process from spawning child processes or writing to protected directories. Effective on Windows endpoints within 30 days.ExtensionSettings in policies.json). These block JavaScript execution on untrusted domains, preventing the exploit payload from running. This is a defense-in-depth measure that also mitigates other browser exploit classes. Deploy within 30 days.- Network-level IDS/IPS signatures — The exploit payload is standard JavaScript served over HTTPS. There is no distinctive network signature; the 256 MB bytecode is generated client-side from a much smaller seed script. DPI cannot detect this.
- WAF rules — This is a client-side vulnerability, not a server-side one. WAF protections are irrelevant.
- Disabling WebAssembly — CVE-2026-8389 is a BaselineJIT bug, not a WebAssembly bug (that's CVE-2026-8390). Disabling Wasm does not help.
- Updating Firefox ESR — ESR is not affected. Patching ESR for this CVE is a no-op; don't let it consume your change window.
The supporting signals.
| In-the-Wild Exploitation | Not observed. Not listed in CISA KEV. No GreyNoise or Shadowserver scanning activity reported. No known campaigns. |
|---|---|
| Proof-of-Concept | Public PoC available. crixpwn/CVE-2026-8389 — 3 commits, includes poc-win-rce.html with a working Windows x64 RCE payload. Originally developed for Pwn2Own 2026 Berlin but patched before the contest. SSVC assessment: *PoC exists, non-automatable, total technical impact*. |
| EPSS | 0.33% probability of exploitation in next 30 days (26th percentile). Low exploitation likelihood per the model, consistent with the high friction of a 256 MB bytecode payload. |
| KEV Status | Not listed. No CISA Known Exploited Vulnerabilities entry as of 2026-09-29. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H — Network-reachable, no privileges, requires user interaction. Secondary assessment by CIRCL scores AC:H (7.5) due to the 256 MB bytecode prerequisite, which noisgate considers more accurate. |
| Affected Versions | Firefox mainline < 150.0.3. Firefox ESR 115.x and ESR 140.x are not listed in MFSA2026-45 and appear unaffected. Thunderbird is not listed as affected. Red Hat packages for RHEL 6-10 track the Firefox package version. |
| Fixed Versions | Firefox 150.0.3 (mainline). RHEL: firefox-150.0.3-1.el8, firefox-150.0.3-1.el9, etc. SUSE: MozillaFirefox-150.0.3-*. Debian/Ubuntu: track upstream Firefox snap or distro package. |
| Researcher | ggwhyp — also credited for CVE-2026-8388, CVE-2026-8391, and CVE-2026-8401 (sandbox escape) in the same MFSA2026-45 batch. Likely a Pwn2Own 2026 Berlin full-chain submission. |
| Disclosure Timeline | Disclosed 2026-05-12 (MFSA2026-45 / Firefox 150.0.3 release). Last modified 2026-07-15. Bugzilla: Bug 2036983. |
| Scanning/Exposure | Not applicable — this is a client-side browser vulnerability, not a server-side exposure. No Shodan/Censys/FOFA dork applies. Firefox telemetry shows ~49% of active Firefox installs are on version 150+, meaning roughly half the Firefox userbase has auto-updated past the vulnerable version. |
Sources.
Why this verdict
- 256 MB bytecode friction: The exploit requires generating >256 MB of compiled bytecode to trigger pcOffset truncation. This causes a multi-second browser freeze, ~2 GB RAM consumption, and is far heavier than typical browser exploit payloads. This pushes real-world attack complexity above the vendor's
AC:Lassessment. Adjustment: −0.3. - Firefox-only with low market share: Firefox holds ~7.5% desktop market share and ~3.7% overall. Enterprise deployments that do use Firefox overwhelmingly run ESR, which is not affected by this CVE (MFSA2026-45 lists only Firefox mainline). The reachable population in a managed enterprise fleet is extremely small. Adjustment: −0.5.
- Content-process sandbox limits blast radius: Successful exploitation lands inside Firefox's content-process sandbox (Win32k lockdown + restricted token on Windows, seccomp-bpf on Linux). Full host compromise requires chaining with a separate sandbox escape. No public PoC exists for the companion CVE-2026-8401 sandbox escape. Without the chain, impact is limited to in-process data theft (session tokens, DOM content). Adjustment: −0.3.
- PoC is public and Pwn2Own-grade (prevents further downgrade): The crixpwn repository contains a demonstrated Windows RCE exploit. While the 256 MB prerequisite adds friction, the PoC is reliable and lowers the bar for skilled attackers. This prevents any downgrade below HIGH.
- Role multiplier: Firefox is a desktop browser occupying workstation roles. (a) *Low-value role* (dev sandbox, lab) — exploitation yields host-level compromise within sandbox, low blast radius. (b) *Typical role* (office workstation) — same constraint, sandbox limits impact. (c) *High-value role* (admin workstation accessing management consoles) — content-process compromise could steal session cookies to admin panels, but this requires the admin to browse to attacker content in Firefox mainline (not ESR). Blast radius: host-level at most, not fleet/domain/identity-scale. Firefox is not a canonical high-value-role component; the floor rule does not elevate this verdict. The worst realistic outcome is credential theft from an admin browser session — serious but not fleet-compromising without additional pivoting.
- No active exploitation: Not KEV-listed, EPSS 26th percentile, no campaigns observed. This supports the downgrade but does not justify dropping below HIGH given the public PoC.
Why not higher?
A CRITICAL rating would require either active in-the-wild exploitation or a blast radius that reaches fleet/domain/identity scale. This vulnerability lands in a sandboxed content process in a browser with ~7.5% desktop market share, and ESR (the enterprise channel) is unaffected. The 256 MB bytecode prerequisite makes automated mass exploitation impractical. Even the companion sandbox escape (CVE-2026-8401) only elevates to host-level compromise, not domain-scale.
Why not lower?
The public Pwn2Own-grade PoC with demonstrated Windows RCE is a hard floor. A skilled attacker can weaponize this against targeted Firefox mainline users — the 256 MB requirement is achievable, not theoretical. Type confusions in JIT compilers are among the most reliable exploitation primitives, and this one has a clean trigger. Dropping to MEDIUM would undervalue the concrete, demonstrated code-execution capability.
Crowdsourced verification payload.
Run this script on each target host where Firefox may be installed. It checks the installed Firefox version against the patched version (150.0.3). Requires no special privileges — any user can run it. Invoke with: bash check_cve_2026_8389.sh
#!/usr/bin/env bash
# check_cve_2026_8389.sh
# Checks whether the installed Firefox is vulnerable to CVE-2026-8389
# (JIT miscompilation in SpiderMonkey BaselineJIT)
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
PATCHED_VERSION="150.0.3"
# Locate Firefox binary
FIREFOX_BIN=""
for candidate in /usr/bin/firefox /usr/lib/firefox/firefox /snap/bin/firefox \
/Applications/Firefox.app/Contents/MacOS/firefox \
"$HOME/Applications/Firefox.app/Contents/MacOS/firefox"; do
if [[ -x "$candidate" ]]; then
FIREFOX_BIN="$candidate"
break
fi
done
if [[ -z "$FIREFOX_BIN" ]]; then
echo "UNKNOWN — Firefox not found on this host"
exit 2
fi
# Get installed version
INSTALLED_VERSION=$($FIREFOX_BIN --version 2>/dev/null | grep -oP '[0-9]+\.[0-9]+\.?[0-9]*' | head -1)
if [[ -z "$INSTALLED_VERSION" ]]; then
echo "UNKNOWN — could not determine Firefox version"
exit 2
fi
# Check if this is ESR (not affected)
IS_ESR=$($FIREFOX_BIN --version 2>/dev/null | grep -ci 'esr' || true)
if [[ "$IS_ESR" -gt 0 ]]; then
echo "PATCHED — Firefox ESR detected ($INSTALLED_VERSION). ESR is not affected by CVE-2026-8389."
exit 0
fi
# Version comparison function
version_gte() {
printf '%s\n%s' "$1" "$2" | sort -V | head -1 | grep -qx "$2"
}
if version_gte "$INSTALLED_VERSION" "$PATCHED_VERSION"; then
echo "PATCHED — Firefox $INSTALLED_VERSION >= $PATCHED_VERSION"
exit 0
else
echo "VULNERABLE — Firefox $INSTALLED_VERSION < $PATCHED_VERSION (CVE-2026-8389)"
exit 1
fi