Understanding React Server Components After Their Worst Day

Photo by Glen Carrie on Unsplash
In light of the recent React Server Components vulnerability, I've become more interested in how RSC protocol actually works. It's hard to ignore a CVSS 10.0 flaw, especially one that lets attackers run arbitrary code on your server without authentication. For context, that means bad actors can access your database, environment variables, secrets, everything. The exploit method might look trivial, but the effects are catastrophic.
While it's an unfortunate reason for being curious, I thought it'd be a good opportunity to dig into the internals myself.
Understanding React Server Components
React Server Components split your component tree into two execution environments:
Server Components run exclusively on the server, with direct access to databases and internal services. Their output is serialized into the RSC Payload: a streaming format that describes the rendered component tree.
Client Components are the traditional React components developers are used to. JavaScript ships to the browser, components hydrate, and you get full interactivity (
useState,useEffect, etc.).Server Functions are async functions marked with
'use server'that clients can call like local functions. Under the hood, React translates these into HTTP requests, deserializes the arguments on the server, and streams results back.
Dan Abramov, one of the core contributors to React, made this really cool app that shows how RSC works under the hood.
This abstraction might look seamless, but as we've recently learned, it comes with hidden security implications.
What Went Wrong
In late November 2025, security researcher Lachlan Davidson discovered a critical flaw in how React deserializes payloads sent to Server Function endpoints, a vulnerability now tracked as CVE-2025-55182 with a maximum CVSS score of 10.0.
The flaw lies in how React deserializes incoming requests to Server Function endpoints. When a client calls a Server Function, React decodes the request payload to reconstruct the function arguments. Attackers could craft malicious payloads that executed arbitrary code during this decoding process without any authentication required.
What makes it worse is that the RSC infrastructure exposes these endpoints automatically, so applications were vulnerable even if they never explicitly used Server Functions. Not only that, after investigation, researchers uncovered more vulnerabilities:
- CVE-2025-55184 (CVSS 7.5 - High): Denial of Service attack vector
- CVE-2025-55183 (CVSS 5.3 - Medium): Source code exposure vulnerability
- CVE-2025-67779 (CVSS 7.5 - High): Found while fixing CVE-2025-55184
The Impact
The exploitation was swift and brutal. Here are a few things that I found after the vulnerability was made public:
Immediate state-sponsored activity: Within hours of public disclosure, Amazon's threat intelligence teams observed active exploitation attempts by China state-nexus threat groups, including Earth Lamia and Jackpot Panda. (AWS Security Blog)
Rapid spread: By December 5th, GreyNoise had tracked 362 unique IP addresses attempting exploitation, while Wiz observed multiple victims compromised starting at 6:00 AM UTC, primarily internet-facing Next.js applications and Kubernetes containers. (GreyNoise, Wiz)
Widespread compromise: Microsoft identified several hundred compromised machines across diverse organizations, with both Windows and Linux environments impacted. (Microsoft Security Blog)
Developer caught in the crossfire: One developer shared his firsthand experience on DEV.to, discovering attackers attempting to download scripts, exfiltrate
.envfiles, and inject base64-encoded payloads into his production app. His hardened Docker setup (read-only filesystem, no shell utilities) prevented full compromise. (DEV.to)Credential harvesting at scale: Wiz observed attackers establishing shells to harvest credentials from environment variables, filesystems, and cloud instance metadata. In one case, an actor was caught attempting to Base64-encode AWS credentials for exfiltration. (Wiz Deep Dive)
Diverse post-exploitation payloads: Trend Micro observed campaigns deploying Cobalt Strike beacons, Nezha, Fast Reverse Proxy (FRP), Sliver payloads, and cryptominers masquerading as system processes like
systemd-devd. (Trend Micro)Nation-state and criminal overlap: Google's Threat Intelligence Group observed activity from China-nexus espionage clusters deploying backdoors (SNOWLIGHT, HISONIC, COMPOOD), as well as Iran-nexus actors and financially motivated cryptomining campaigns. (Google Cloud Blog)
Default configs were sitting ducks: The exploit had near-100% reliability against default configurations. A vanilla Next.js app created with
create-next-appwas immediately vulnerable with no code changes required. (Unit 42)
On a personal note, I've seen some people that I know got impacted by the vulnerability: servers and containers got compromised, CPU usage going through the roof, realizing that their servers became a crypto miner for someone else. Reading through forums and subreddits, I found other people having similar scenarios. What's worse is that they can't do anything about it. They tried deleting the malicious scripts, it only comes back like nothing happened. They had to nuke their servers, delete their containers, and rebuild everything from scratch.
While the impact was so severe, I was lucky enough that my projects, both work and personal, aren't affected, though I had to patch them to avoid being compromised.
Perspective from a Software Engineer
The recent incident made me remember one of the fundamentals in programming: abstractions hide complexity; they don't remove it. Though RSC's abstraction was designed with good intentions, underneath it still exposes an HTTP endpoint accepting input from the internet, making it open to bad actors. The deserialization layer became an attack surface most developers never thought about, because they never had to write it themselves.
PS: If you're using React Server Components in production, patch now.
