Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-14321 | Kitploit
Tools/GitHubGitHub/h3raklez/cve-2025-14321
Vulnerability AnalysisExploitationWeb Application ExploitationCTFPapers & ResearchLearning & EducationBinary Exploitation
GitHubh3raklez/cve-2025-14321

CVE-2025-14321

View Repository
26 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2025-14321 Proof of Concept

Description

PoC for a Use-After-Free (UAF) vulnerability in the RTCEncodedFrameBase component of Firefox, exploitable via the WebRTC Encoded Transforms API.

CVE-2025-14321: The destructor of RTCEncodedFrameBase does not call DetachArrayBuffer() when releasing the native memory of the frame. As a result, JavaScript ArrayBuffers retain pointers to already freed memory (dangling pointers), allowing arbitrary read and write on the heap of the Firefox content process.

This PoC has been tested on Mozilla Firefox 145.0.1 and Windows 10.

Root cause

Firefox exposes encoded video/audio frames as JavaScript ArrayBuffers via NewArrayBufferWithUserOwnedContents(). When the native (C++) frame is destroyed, the backing memory of the ArrayBuffer is freed, but the JavaScript ArrayBuffer is not detached. This violates the ownership invariant and creates a dangling pointer.

Vulnerable code (dom/media/webrtc/jsapi/RTCEncodedFrameBase.cpp):

root@kitploit:~
// ❌ Destructor does not detach the ArrayBuffer
RTCEncodedFrameBase::~RTCEncodedFrameBase() = default;

Patched code:

root@kitploit:~
// ✅ Detaches the ArrayBuffer before freeing native memory
RTCEncodedFrameBase::~RTCEncodedFrameBase() {
  DetachData();
}

Affected versions

  • Firefox < 146
  • Firefox ESR < 140.6

Primitives obtained

  • READ: new Uint8Array(buf) reads data from memory reallocated to other heap objects
  • WRITE: new Uint8Array(buf).fill(0x41) corrupts adjacent heap objects (vtables, DOM structures, etc.)

These primitives are sufficient to demonstrate the vulnerability. With additional heap shaping, they could be escalated to remote code execution (RCE).

Prerequisites

Firefox configuration (about:config)

root@kitploit:~
media.peerconnection.scripttransform.enabled = true
media.peerconnection.ice.loopback             = true
media.peerconnection.ice.no_host              = false
media.peerconnection.ice.relay_only           = false
media.peerconnection.ice.proxy_only           = false

⚠ Restart Firefox after modifying preferences.

Camera permission (optional)

The PoC attempts to request camera access via getUserMedia(). This is not mandatory if ICE preferences are correctly set. Its purpose is to promote Firefox to RFC IP handling mode 1, which guarantees generation of ICE host candidates in scenarios where the preferences alone are not sufficient.

In practice:

  • VM without camera: getUserMedia() fails silently (NotFoundError) without showing a prompt. ICE still connects thanks to media.peerconnection.ice.loopback = true.
  • System with camera: Firefox shows the permission prompt. Accepting it ensures ICE mode 1.
  • Camera denied: The PoC uses a canvas as fallback. ICE can connect if the preferences are set correctly.

HTTP server

Web Workers do not work from file://. Serve via HTTP:

root@kitploit:~
python3 -m http.server 8080

Open in vulnerable Firefox: http://localhost:8080/poc-cve-2025-14321.html

Exploit flow

1. getUserMedia → ICE mode 1 (best-effort)

The PoC attempts to request camera access. If a camera is available and the user accepts, Firefox promotes the session to RFC IP handling mode 1. If getUserMedia() fails (VM without camera, permission denied), the PoC continues with a canvas as frame source — ICE still connects if media.peerconnection.ice.loopback = true is active.

2. Animated canvas as frame source

A <canvas> of 320×240 with animation at 30fps is created via captureStream(30). This generates predictably encoded video frames. Once ICE connects and the camera was used, the PoC replaces the camera track with the canvas track via replaceTrack() and releases the camera.

3. WebRTC loopback connection

Two local RTCPeerConnection objects are created (pc1 ↔ pc2) with standard SDP negotiation and trickle ICE. Candidates are exchanged directly between peers.

4. Transform Worker (RTCRtpScriptTransform)

An RTCRtpScriptTransform is assigned to the sender of pc1 before SDP negotiation. The worker intercepts each encoded frame from the send pipeline.

5. Retention of ArrayBuffers (200 frames)

For each of the first 200 frames, the worker:

  1. Extracts frame.data (ArrayBuffer pointing to native memory)
  2. Saves the reference in an array (leaks[])
  3. Writes a known pattern: new Uint8Array(buf).fill(0x41)
  4. Does NOT forward the frame → the native wrapper is destroyed → memory is freed

By not forwarding, the GC destroys the C++ wrapper and frees the native memory. But the JavaScript ArrayBuffer retains the pointer — dangling pointer created.

6. UAF detection

Starting from frame 201, every 3 frames the worker:

  1. Reads the first 16 bytes of each retained buffer
  2. If any byte differs from 0x41, the allocator reused that memory → UAF confirmed
  3. Rewrites 0x41 over the buffer (write primitive on foreign heap)

This read/write cycle on freed memory causes progressive heap corruption until Firefox crashes the tab (equivalent to SIGSEGV reported in the advisory).

Expected results

Vulnerable version (Firefox < 146)

root@kitploit:~
[0.4s] ✓ Initial track: canvas (fallback)
[0.4s] ✓ ICE CONNECTION ESTABLISHED!
[0.5s] ▶▶▶ FIRST ENCODED FRAME RECEIVED! ◀◀◀
[0.5s] Leak #0: 1219B → 41414141414141414141414141414141
[2.7s] Leak #49: 1497B → 41414141414141414141414141414141
[9.8s] Leak #199: 1870B → 41414141414141414141414141414141
[9.9s] 200 ArrayBuffers retained → native memory already freed
[9.9s] → Dangling pointers active, waiting for reuse…
       [ TAB CRASH — heap corruption]

Note: If a camera is available and permission is granted, the log will show ✓ getUserMedia granted — ICE mode 1 active and later ✓ Track replaced: camera → canvas after ICE connection. On VMs without camera, the PoC uses canvas directly without prompt.

The tab crash confirms heap corruption: writing 0x41 over memory reallocated to other objects (vtables, DOM nodes) causes an invalid memory access in the content process.

Patched version (Firefox ≥ 146)

root@kitploit:~
✓ Buffer[0] detached correctly — fix active
ArrayBuffer detached — patched version ✓

The DetachData() in the destructor invalidates the ArrayBuffer before freeing native memory, eliminating the dangling pointer.

Project structure

root@kitploit:~
├── poc-cve-2025-14321.html            # Functional PoC (readable source code)
└── README.md                          # This file

The patch

Mozilla fixed the vulnerability in Firefox 146 by adding DetachData() in all destructors and teardown paths of RTCEncodedFrameBase.

Commit: https://hg-edge.mozilla.org/mozilla-central/rev/1051067f6e83

Mitigation

  • Update Firefox to version 146 or higher
  • Update Firefox ESR to version 140.6 or higher

Disclaimer

⚠ FOR EDUCATIONAL AND RESEARCH PURPOSES ONLY

This PoC demonstrates the existence of the vulnerability up to the point of heap corruption (crash). It does not implement heap shaping, ASLR bypass, or hijack techniques necessary for code execution. Its purpose is exclusively verification and understanding of the CVE in controlled environments.

References

  • CVE: CVE-2025-14321
  • Blog post: https://aisle.com/blog/firefox-webrtc-encoded-transforms-uaf-via-undetached-arraybuffer-cve-2025-14321
  • Advisory: MFSA 2025-92 · Bug 1992760
  • Mozilla commit: https://hg-edge.mozilla.org/mozilla-central/rev/1051067f6e83

Credits

  • Discovered by: Igor Morgernstern, AISLE Research Team
  • Report date: 2025-10-06
  • Patch date: 2025-11-19
  • Publication date: 2025-12-09
Download Tool