The December 2025 security advisory from the React team marks a paradigm shift in web application security. As the industry rapidly adopts Server-Side Rendering (SSR) via React Server Components (RSC), the attack surface has migrated from the client DOM to the server’s serialization boundary. CVE-2025-55184 is not a trivial resource exhaustion bug; it is a sophisticated Algorithmic Complexity Denial-of-Service targeting the Node.js Event Loop’s fundamental architecture. By exploiting the recursive deserialization of Promises within the Flight Protocol, an unauthenticated attacker can induce Microtask Queue Starvation, rendering the server process comatose while keeping TCP ports open. This definitive guide dissects the vulnerability at the wire level, explores the “Ouroboros” recursion mechanic, and demonstrates how Sträflich leverages AI-driven differential fuzzing to validate this flaw without disrupting production availability.

The Architecture of a Crash: RSC, Flight, and the Event Loop
To fully appreciate the severity of CVE-2025-55184, we must first deconstruct the proprietary communication layer that powers Next.js App Router and React 19: the Flight Protocol.
The Flight Protocol Wire Format
Unlike REST or GraphQL, which typically return static JSON, RSC uses a hybrid row-based streaming format designed to resolve component trees incrementally.
A typical Flight response stream looks like this:
HTTP
1:I{"id":134,"chunks":["app/page.js"],"name":"default"} 2:{"title":"Welcome","content":"$@1"} 3:{"$":"$@2"}
- Line 1: Imports a module (Client Component).
- Line 2: Defines a JSON object referencing chunk 1.
- Line 3: Defines a reference to chunk 2.
The Fatal Feature: Asynchrony Serialization
React allows developers to pass Promises from the server to the client. When the serializer encounters a pending Promise, it emits a placeholder. The deserializer (on the receiving end, which can also be a server in tiered architectures) is programmed to wait for these Promises to resolve.
This requirement necessitates a Recursive Resolution Strategy: If Promise A resolves to Promise B, the deserializer must subscribe to Promise B. This recursion is where the vulnerability lies.
Node.js Internals: Microtask Queue Starvation
Why is this exploit so devastating compared to a standard while(true) loop? The answer lies in the V8 engine’s task scheduling.
- Macrotasks: Timers (
setTimeout), I/O callbacks,setImmediate. - Microtasks: Promise callbacks (
.then,.catch),process.nextTick.
The Starvation Mechanic:
The Node.js Event Loop operates on a strict priority rule: The Microtask Queue must be completely drained before the Event Loop can proceed to the next phase.
In a CVE-2025-55184 exploit, the attacker sends a payload where a Promise resolves to itself (or a chain leading back to itself).
- The deserializer schedules a
.then()to handle the resolution. - The callback runs, sees the recursion, and schedules another
.then(). - Crucially, this happens synchronously regarding the queue processing. The queue length never hits zero.
- Auswirkungen: Network I/O callbacks (handling new requests), Health Check probes, and OS signals are permanently blocked. The process is alive (PID exists), ports are open (SYN-ACK works at OS level), but the application is brain-dead.
Reverse Engineering the Exploit
The “Ouroboros” Payload
The vulnerability exists in react-server-dom-webpack (and its variants for Parcel/Turbopack). The unpatched processValue function lacked depth limiting or cycle detection for reference types.
An attacker can weaponize this by constructing a Directed Cyclic Graph (DCG) within the Flight payload.
Conceptual Exploit Code (Protocol Level)
While the actual binary encoding is complex, the logical structure of the attack vector is elegantly simple:
JavaScript
`// A JSON representation of the malicious Flight structure // Target: Next.js App Router Endpoint (POST /)
{ “id”: “root”, “chunks”: [], “value”: { // We define a Promise object manually using Flight syntax “$”: “$Promise”, “status”: “fulfilled”, “value”: { // The value of this resolved promise is… ITSELF. “$”: “$@root” } } }`
When the server parses this:
- It sees a fulfilled Promise.
- It unwraps the value.
- It sees a reference to the root object (which is the Promise).
- It schedules a microtask to unwrap the root object again.
- GOTO 1.
This loop happens entirely in memory, bypassing traditional WAFs that look for SQL injection signatures or large request bodies. The payload is often smaller than 1KB.
The “Incomplete Fix” Saga (CVE-2025-67779)
It is vital to note that the initial patch for this vulnerability was bypassed within days. The first fix attempted to track recursion depth but failed to account for certain nested structure variations (e.g., wrapping the cycle inside a Map oder Set). This led to CVE-2025-67779. Therefore, simply “updating” is not enough; one must ensure they are on the definitive patched versions (React 19.0.3+ / Next.js 15.0.6+).
The Silent Partner: CVE-2025-55183 (Source Code Exposure)
While 55184 destroys availability, CVE-2025-55183 destroys confidentiality. This companion vulnerability was disclosed simultaneously.
The Leak Mechanism:
Server Actions are internal functions. However, if an attacker requests a Server Action by ID as a value (instead of invoking it), the vulnerable serializer treats it as a data object. In doing so, it serializes the compiled function body as a string.
Auswirkungen:
- Logic Extraction: Attackers can read your backend validation logic (
if (!user.isAdmin) ...). - Secret Scraping: Hardcoded API keys or internal endpoints are revealed.
- Shadow API Discovery: Unused or hidden Server Actions become visible attack targets.
Advanced Verification: The Penligent Approach
In a high-stakes environment, “trying to crash the server” to prove a vulnerability is unprofessional and dangerous. Sträflich utilizes AI-driven Safe Exploitation strategies to verify these CVEs with zero downtime.
Strategy 1: Bounded Recursion Probing (Safe DoS)
Instead of an infinite loop, the Penligent AI Agent constructs a payload with a Finite Recursion Depth ($N=5000$).
- The Probe: A recursive Promise chain that terminates after 5000 iterations.
- Heuristic Analysis:
- Vulnerable: The server processes the chain. Penligent detects a distinct Latency Drift (e.g., response time = baseline + 200ms) and a transient spike in heap usage.
- Patched: The new security mechanism in React 19 throws a “Cyclic Reference” error immediately. The response is near-instantaneous (500 Internal Server Error).
- Schlussfolgerung: If latency correlates with depth ($T \propto N$), the vulnerability is confirmed without hanging the process.
Strategy 2: Differential Fuzzing for Source Leaks (CVE-2025-55183)
To detect the source code exposure vulnerability:
- Fingerprinting: Penligent identifies available Server Action IDs from legitimate client-side bundles.
- Reflective Injection: The agent sends modified Flight requests attempting to “echo” these IDs as data properties.
- Pattern Matching AI: The response stream is analyzed. If the AI detects JavaScript function signatures (e.g.,
async function $...,var _0x...) within the JSON response, it flags a Critical Information Leak.

Engineer’s Action Plan & Remediation
The window for exploitation is wide open. Automated bots are already scanning for exposed Next.js 15.0.x instances.
1. The Upgrade Matrix (Strict Enforcement)
You must ensure your dependency tree resolves to the safe versions. Do not rely on semver carets (^) alone; check your pnpm-lock.yaml oder package-lock.json.
| Package | Vulnerable Range | Safe Version (Minimum) |
|---|---|---|
| react-server-dom-webpack | < 19.0.3 | 19.0.3 |
| Nächste.js | 15.0.0 – 15.0.5 | 15.0.6+ (or 14.2.34+ for v14) |
2. Dependency Resolution Overrides
Because react-server-dom-webpack is often a nested dependency, you should force the resolution in package.json to prevent older versions from sneaking in:
JSON
// package.json { "pnpm": { "overrides": { "react-server-dom-webpack": "19.0.3", "react-server-dom-turbopack": "19.0.3" } } }
3. Continuous Validation
Security is not a one-time patch. Use Sträflich to continuously monitor your deployment. As new bypasses (like the one seen in CVE-2025-67779) emerge, Penligent’s AI models are updated to test for these variations, ensuring your perimeter remains impenetrable against evolving logic attacks.
References & Authority Links:
- React Security Advisory: Denial of Service and Source Code Exposure
- Next.js Official Security Update (December 2025)
- Node.js Docs: The Event Loop, Timers, and process.nextTick()
- NIST NVD – CVE-2025-55184 Detail


