React/Next.js stack-overflow DoS via RSC reply cycles
- https://www.youtube.com/watch?v=y5tlwWVYPek
- Original title: I Tried to Warn You
Prime walks through the latest Next.js CVE wave (multiple middleware bypasses, DoS, XSS, SSRF, cache poisoning) and dissects the top one — an unauthenticated stack-overflow DoS in React Server Components' reply parser. Uses it as a lap around why he's been jaded on React since 2016 and pitches HTMX as the saner path.
The vulnerability
- Bug lives in React itself (not just Next.js), in
parse_model_string/get_outlined_model/initialize_model_chunk/revive_modelpath used by React Server Components replies. - Pre-patch React walked the reply graph during model resolution with no depth, cycle, or row-count limit.
- Attacker crafts a form-encoded reply body with
next-actionheader pointing to an app-router page. Object references form a ring (last element refers back to first). - Resolution loops parse_model → get_outlined_model → initialize_model_chunk → revive_model → parse_model_string indefinitely.
- ~53,000 iterations exhausts Prime's stack; cheap EC2 servers blow up much sooner.
- JS is effectively single-threaded → one request pegs CPU for hundreds of ms, denies all other requests, eventually crashes the process. Unauthenticated.
Context
- Reproductions live in a "slop-pository" (bash piping to Python, AI-shaped code) linked from CVE.
- Previous RCE in same code path: subclass "B" (Blob) handling stringified a user-controlled string into an executable JS function.
- This one uses uppercase "F" (forward reference) instead.
Prime's takes
- "Forced upgrades will continue until morale improves or you switch to HTMX."
- RSC's value prop (avoid N+1, CDN-cache initial HTML up to first Suspense, then stream user-specific data) is "a lot of engineering just to avoid thinking about how to load data."
- Hands-off-the-HTML promise of React leaks: underlying code uses
dangerouslySetInnerHTMLand fails to escape properly → XSS CVE in the same batch. - Brief Netflix-2016 confession: helped push React onto TVs, benchmark was rigged (skinny new app vs. decade-old legacy app). Lesson: "just say no early on."
Action item
- Upgrade React even if not using Next.js. The cycle parser is in React core (
react-server-dom-webpack).