A High-Severity WebAssembly Boundary Condition Vulnerability in Firefox: CVE-2025-13016
Author
Stanislav Fort
Date Published
.webp%3F2025-11-24T18%3A57%3A08.980Z&w=3840&q=100)
AISLE discovered a stack buffer overflow in Firefox's WebAssembly engine that evaded detection for six months despite shipping with its own regression test. The vulnerability, CVE-2025-13016, enabled arbitrary code execution through a single line of incorrect pointer arithmetic, affecting over 180 million Firefox users worldwide.
Introduction
For six months, a subtle pointer arithmetic error in Firefox's WebAssembly implementation silently wrote past stack buffers in hundreds of millions of browsers worldwide. The vulnerability, CVE-2025-13016, was particularly insidious: Mozilla had added a regression test alongside the vulnerable code in April 2025, yet the stack buffer overflow went completely undetected until Aisle's autonomous analyzer found it in October 2025.
A single line of template code, mixing uint8_t* and uint16_t* pointers in a
std::copy operation, created a memory corruption vulnerability that could
allow attackers to execute arbitrary code. With a CVSS score of 7.5 (High),
this flaw affected all Firefox versions from 143 through early 145, and Firefox
ESR versions before 140.5, potentially exposing over 180 million monthly
active users to exploitation.
What makes this discovery particularly striking is the gap between the bug's subtlety and its potential impact. The vulnerable code passed code review, included a test specifically designed to exercise the same code path, and shipped in multiple Firefox releases. Yet it took Aisle's autonomous analyzer to identify what human reviewers and conventional testing missed: a memory safety violation hiding in plain sight within Firefox's WebAssembly garbage collection logic.
The Technical Details
The Vulnerable Code
The vulnerability resides in Firefox's StableWasmArrayObjectElements template
class, specifically in how it handles copying inline WebAssembly array data. The
issue is located in js/src/wasm/WasmGcObject.h at line 532 (in the vulnerable
version).
Here's the problematic code from the original implementation:
C1template <typename T>2class MOZ_RAII StableWasmArrayObjectElements {3 static constexpr size_t MaxInlineElements =4 WasmArrayObject::maxInlineElementsForElemSize(sizeof(T));5 Rooted<WasmArrayObject*> array_;6 T* elements_;7 mozilla::Maybe<mozilla::Vector<T, MaxInlineElements, SystemAllocPolicy>>8 ownElements_;910 public:11 StableWasmArrayObjectElements(JSContext* cx, Handle<WasmArrayObject*> array)12 : array_(cx, array), elements_(nullptr) {13 if (array->isDataInline()) {14 ownElements_.emplace();15 if (!ownElements_->resize(array->numElements_)) {16 MOZ_CRASH();17 }18 // VULNERABLE CODE:19 std::copy(array->inlineStorage(),20 array->inlineStorage() + array->numElements_ * sizeof(T),21 ownElements_->begin());22 elements_ = ownElements_->begin();23 } else {24 elements_ = reinterpret_cast<T*>(array->data_);25 }26 }27};
Understanding the Bug
The vulnerability manifests in two distinct ways:
1. Buffer Overflow via Incorrect Pointer Arithmetic
The std::copy call uses uint8_t* pointers from inlineStorage() but
performs byte arithmetic to calculate the endpoint. However, std::copy
interprets all three arguments as having the same type. When the template is
instantiated with T = uint16_t, the algorithm copies
numElements_ * sizeof(T) elements (not bytes), resulting in writing twice as
much data as intended.
For example, with an array of 50 16-bit elements, the code writes 100 uint16_t
values instead of 50, overflowing the stack-allocated vector's inline capacity.
2. Wrong Data Source
The inlineStorage() method returns a pointer to the storage area that begins
with a DataHeader, not the actual array elements. The code should have used
addressOfInlineData() instead, which points to the data after the header. This
means the first 8 bytes copied are metadata rather than array contents.
How the Vulnerability is Triggered
The bug becomes exploitable when Firefox's WebAssembly engine needs to create a
stable copy of inline array data during garbage collection. This occurs in the
Instance::stringFromCharCodeArray function in js/src/wasm/WasmInstance.cpp:
C1/* static */2void* Instance::stringFromCharCodeArray(Instance* instance, void* arrayArg,3 uint32_t arrayStart,4 uint32_t arrayEnd) {5 JSContext* cx = instance->cx();6 RootedAnyRef arrayRef(cx, AnyRef::fromCompiledCode(arrayArg));7 Rooted<WasmArrayObject*> array(cx, UncheckedCastToArrayI16<true>(arrayRef));89 uint32_t arrayCount = arrayEnd - arrayStart;1011 // First attempt with NoGC12 JSLinearString* string = NewStringCopyN<NoGC, char16_t>(13 cx, (char16_t*)array->data_ + arrayStart, arrayCount);1415 if (!string) {16 // VULNERABLE PATH: Falls back to stable copy17 StableWasmArrayObjectElements<uint16_t> stableElements(cx, array);18 string = NewStringCopyN<CanGC, char16_t>(19 cx, (char16_t*)stableElements.elements() + arrayStart, arrayCount);20 // ...21 }22}
When the initial NoGC string allocation fails (during memory pressure or GC),
the code creates a StableWasmArrayObjectElements instance. This triggers the
vulnerable copy operation.
Demonstrating the Vulnerability
The vulnerability could be triggered through WebAssembly code that creates arrays with specific element types and counts, then invokes string conversion operations under memory pressure conditions. When the fast-path NoGC allocation fails, Firefox's fallback mechanism activates the vulnerable code path. With properly sized arrays, the overflow writes past the stack-allocated vector's capacity.
Mozilla's internal testing with memory sanitizers confirmed the stack buffer
overflow, showing writes beyond the intended buffer boundaries in the
StableWasmArrayObjectElements constructor.
The Fix
Mozilla's Yury Delendik implemented, after our responsible disclosure, a straightforward fix that addresses both issues. The corrected code properly handles type conversions and uses the correct data pointer:
C1if (array->isDataInline()) {2 ownElements_.emplace();3 if (!ownElements_->resize(array->numElements_)) {4 MOZ_CRASH();5 }6 // FIXED CODE:7 const T* src = array->inlineArrayElements<T>();8 std::copy(src, src + array->numElements_, ownElements_->begin());9 elements_ = ownElements_->begin();10}
The fix introduces the inlineArrayElements<T>() helper method that returns a
properly typed pointer to the array data (after the header):
C1template <typename T>2T* inlineArrayElements() {3 return offsetToPointer<T>(offsetOfInlineArrayData());4}
This ensures that std::copy receives correctly typed pointers and copies
exactly numElements_ elements of type T.
Timeline and Disclosure
The vulnerability demonstrates both the challenges of memory-safe programming and the effectiveness of coordinated disclosure:
- April 7, 2025: Vulnerable code introduced in Firefox via Bug 1956768
- October 2, 2025: Aisle's autonomous analyzer discovers the vulnerability
- October 2, 2025: Igor Morgenstern from Aisle reports the issue to Mozilla immediately
- October 14, 2025: Mozilla security team triages and confirms the vulnerability
- October 15, 2025: Fix developed and committed to mozilla-central
- October 16, 2025: Fix verified on nightly builds
- October 22, 2025: Fix uplifted to Firefox 145 beta and ESR 140.5
- November 11, 2025: Public disclosure with Firefox 145 and ESR 140.5 releases
From discovery to fix in just 14 days, this timeline showcases the efficiency of modern coordinated vulnerability disclosure. Mozilla recognized the discovery with a substantial security bug bounty, acknowledging both the severity of the vulnerability and the quality of the report.
Impact and Affected Versions
Vulnerability Assessment
The National Vulnerability Database assigned CVE-2025-13016 a CVSS v3.1 score of 7.5 (High) with the vector:
Shell1CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H
This scoring reflects:
- Attack Vector (AV:N): Network-based, exploitable via malicious websites
- Attack Complexity (AC:H): High complexity; requires precise timing to trigger GC during the vulnerable code path
- Privileges Required (PR:N): No privileges needed
- User Interaction (UI:R): Requires user to visit a malicious page
- Scope (S:U): Unchanged; impact limited to Firefox process
- Confidentiality/Integrity/Availability (C:H/I:H/A:H): High impact on all three
Affected Software
Vulnerable Versions:
- Firefox versions 143, 144, and 145 (before the fix)
- Firefox ESR 140.0 through 140.4
Patched Versions:
- Firefox 145 and later
- Firefox ESR 140.5 and later
Not Affected:
- Firefox ESR 115 (older version without WebAssembly GC support)
- All Firefox versions prior to 143
The vulnerability affected all platforms supported by Firefox: Windows, macOS, Linux, and Android. Given Firefox's substantial user base of over 180 million monthly active users, the potential impact was significant.
How Long Did the Bug Hide?
The vulnerable code was introduced on April 7, 2025, through Mozilla Bug
1956768. Ironically, that same commit added a regression test using oomTest()
to verify the code path's correctness. However, the test didn't detect the
vulnerability because:
- Without AddressSanitizer, stack buffer overflows into reserved inline capacity often remain silent
- The test only verified 4 characters of output, missing data corruption beyond that range
- The test primarily succeeded via the fast NoGC path, avoiding the vulnerable fallback
The bug lived in Firefox for approximately 6 months before Aisle's analyzer discovered it, spanning Firefox versions 143 through early 145. During this period, the vulnerability was present in multiple Firefox releases used by millions globally.
Broader Ecosystem Impact
Firefox serves as a critical component of the web ecosystem, and vulnerabilities in its WebAssembly engine have cascading effects:
Distribution Channels
Linux distributions rapidly incorporated the security update:
- Ubuntu: Security advisory for Firefox packages
- Debian: Updated packages in stable and testing branches
- Fedora: Fast-tracked security update
- Arch Linux: Updated within 24 hours of release
- Red Hat Enterprise Linux: Security advisory RHSA-2025:XXXX
WebAssembly Ecosystem
This vulnerability highlights security challenges in WebAssembly implementations:
- WebAssembly's low-level memory model requires extreme care in C++ implementations
- The interaction between garbage collection and memory operations creates subtle attack surfaces
- Comprehensive testing, including memory sanitizers, is essential for memory-unsafe languages
Mitigation Guidance
For End Users
Immediate Actions:
- Update Firefox immediately to version 145 or later (or ESR 140.5+)
- Enable automatic updates: Settings → General → Firefox Updates
- Restart Firefox after the update to ensure the new version is running
Verification:
- Navigate to `about:support` in Firefox
- Confirm "Version" shows 145.0 or higher (or 140.5+ for ESR)
For System Administrators
Enterprise Deployments:
Shell1# Verify Firefox version across fleet2firefox --version34# For ESR deployments5firefox-esr --version
Temporary Mitigation (if immediate patching is not possible):
- Disable WebAssembly via `about:config`:Set `javascript.options.wasm` to `false` Note: This breaks legitimate WebAssembly applications
However, these mitigations significantly impact functionality. Updating Firefox remains the only complete solution.
The Role of Autonomous Security Analysis
This discovery exemplifies the power of autonomous security analysis. Aisle's analyzer, piloted by researcher Igor Morgenstern, systematically examined Firefox's WebAssembly implementation and identified the boundary condition error without prior knowledge of the code's structure.
Why Automated Analysis Matters
Traditional security testing methods struggle with issues like CVE-2025-13016:
- Manual code review: The bug hides in template-heavy C++ code with complex type conversions
- Fuzzing: Requires hitting precise conditions (GC pressure during specific WebAssembly operations)
- Static analysis: Must reason about template instantiation and pointer arithmetic across type boundaries
Aisle's autonomous analyzer excels at:
- Systematically exploring complex codebases
- Understanding semantic relationships between data structures
- Identifying subtle memory safety violations
- Building a stack model of code interconnections and flagging issues in the logical design of the system itself
Our analyzer identified the vulnerability and provided detailed analysis that accelerated Mozilla's response and remediation efforts.
Conclusion
CVE-2025-13016 serves as a reminder that even mature, well-tested codebases can harbor critical vulnerabilities. The bug existed in Firefox for six months, passed code review, and even had a regression test added alongside it. Yet it remained undetected until Aisle's autonomous analyzer found it.
We commend Mozilla's security team for their rapid response and thorough remediation. From our initial report to public release, the entire process took just 40 days, demonstrating Mozilla's commitment to user security. The coordinated disclosure process worked as intended, allowing users to receive patches before attackers could develop exploits.
This discovery reinforces Aisle's mission: to secure the world's critical software infrastructure through autonomous security analysis. As software systems grow more complex, autonomous analyzers will play an increasingly vital role in finding vulnerabilities before adversaries do.
Learn More
Interested in Aisle's autonomous security platform? Visit us at aisle.com or reach out to [email protected].
References
Official Mozilla Advisories:
- Mozilla Foundation Security Advisory 2025-87 (Firefox 145)
- Mozilla Foundation Security Advisory 2025-88 (Firefox ESR 140.5)
Vulnerability Databases:
- CVE-2025-13016 (National Vulnerability Database)l
- Mozilla Bug 1992130 (Bug tracker)
Technical Details:
- Firefox Source Repository (Fix commits)
- Commit: 75ef3f79aae3 (mozilla-central)
- Commit: b7ac28fbaa5b (Firefox 145 beta)
- Commit: f355864bb44f (Firefox ESR 140\)
CVE-2025-13016 was discovered by Aisle's autonomous analyzer and reported by Igor Morgenstern. The vulnerability was responsibly disclosed to Mozilla and patched in Firefox 145 and ESR 140.5.