Status: Patched
This vulnerability has been verified as resolved and deployed.
RSC reply decoder DoS via $K FormData amplification (CVE-2026-23864)
Summary
Unbounded $K expansions allow FormData amplification during RSC reply decoding
The server-side React Flight reply decoder treats $K<id> tokens as nested FormData and reconstructs them by scanning the backing request form and copying entries into a new FormData. Because the decoder performs a full scan and allocation for every $K occurrence with no global limits, an attacker can embed thousands of $K tokens in a small multipart payload and force the server to allocate tens of MB of heap while decoding. This creates a high-amplification DoS that is remotely reachable via Server Actions in frameworks that call decodeReplyFromBusboy.
Write-up
decodeReply and decodeReplyFromBusboy materialize a response with _formData as the backing store, then parse chunk 0 through initializeModelChunk and reviveModel. Every string value flows into parseModelString, where $K<id> is interpreted as a nested FormData.
The $K handler builds a new FormData and performs a full scan of _formData to copy all matching prefixed entries. There is no validation of the id, no memoization, and no global limits on $K occurrences or copied entries.
As a result, a small multipart payload can include a large array of $K tokens and force repeated scans and allocations (CPU O(M * E), memory O(M * N)), amplifying a sub-megabyte request into tens or hundreds of MB of heap usage. This is remotely reachable via Server Actions in frameworks that call decodeReplyFromBusboy, making it a practical high-amplification DoS.
CVSS Score
Vulnerability Location
Sink-to-Source Analysis
parseModelString sees $K<id> and constructs a new FormData, then scans the entire backing request form for keys with the matching prefix.
Each $K token triggers a full scan and a new FormData allocation, with no cap on occurrences or copied entries.
decodeReplyFromBusboy populates the response by resolving multipart fields, making the $K path reachable from HTTP Server Action requests.
resolveField appends every incoming field into _formData, enabling an attacker to control the number and size of entries that are copied per $K token.
Impact Analysis
Critical Impact
A small (<1 MB) request can force tens to hundreds of MB of allocations while decoding, resulting in memory exhaustion or severe CPU pressure. Repeated requests can crash the server or degrade service availability.
Attack Surface
Any server that decodes untrusted React Flight reply payloads, including frameworks that use Server Actions / Server Functions with multipart bodies (e.g., Next.js).
Preconditions
Attacker can send a crafted multipart request to a Server Action endpoint. No authentication is required if the endpoint is publicly reachable.
Proof of Concept
Environment Setup
Create a local repro:
Target Configuration
Save the following as repro.cjs:
Exploit Delivery
Run the PoC:
Outcome
The decoder allocates thousands of new FormData objects and copies entries on each $K, producing large heap growth from a small input.
Expected Response:
