Tekunda Team
How React2Shell Led to Cryptomining in React and Nextjs Apps
TL;DR: In early December 2025, a critical vulnerability known as React2Shell (CVE-2025-55182) was disclosed in React Server Components. The issue allowed unauthenticated remote code execution in common React and Next.js setups, including default configurations. Exploits appeared quickly in the wild, with compromised servers used for cryptomining. If your application uses React Server Components or the Next.js App Router, patching and redeployment are required.
For years, frontend engineers were taught a reassuring mental model: The browser is the boundary.
Frontend code ran on the client, backend systems handled trust and security, and frameworks helped keep those responsibilities clearly separated. That model shaped how teams reasoned about risk, reviews, and deployment.
React2Shell broke that assumption in a very practical way.
In the days following the disclosure of CVE-2025-55182, teams across different roles reached the same conclusion from different direction, not because of theory, but because of what attackers did next.
Modern React applications are no longer just UI code. They execute as part of production infrastructure, and that shift made it possible for opportunistic campaigns to turn exposed servers into cryptomining workloads.
This wasn’t caused by misuse or exotic configurations. It widely affected adopted versions of React and Next.js running exactly as documented, which is why the impact spread quickly.
What Happened in React2Shell?
React2Shell is a critical vulnerability in React Server Components (RSC), a React feature that allows parts of frontend code to run on the server as part of handling real user requests.
What made this vulnerability different was not just where it lived, but how naturally it fit into normal request handling.
The vulnerability allowed attackers to trigger remote code execution (RCE), a class of attack where someone can run their own commands on a server by sending a specially crafted request, without logging in.
At a high level, the attack unfolded as follows:
- A crafted request reached server-side React logic
- Serialized input crossed a trust boundary
- The server executed attacker-controlled code
Once that chain was understood, the severity became obvious.
The severity was immediately clear:
- CVSS score: 10.0 (Critical)- the highest severity rating
- Unauthenticated
- Remote
- Production impact
Proof-of-concept exploits appeared shortly after disclosure. Active exploitation followed soon after, leaving little time between understanding and exposure.
Why Default Applications Were Exposed?
One of the most important lessons from React2Shell is how ordinary the affected setups were. That ordinariness is exactly why the impact spread so quickly.
These were not:
- Custom forks
- Unsafe experimental builds
- Edge-case deployments
They were:
- React applications using these vulnerable packages (versions 19.0.0, 19.1.0, 19.1.1, 19.2.0):
- Next.js versions ≥14.3.0-canary.77, 15.x, and 16.x using the App Router
- Other affected frameworks: React Router (unstable RSC APIs), Expo, Redwood SDK, Waku, and Vite/Parcel RSC plugins
React Server Components fundamentally change where frontend logic runs. As a result, frontend code now:
- Executes on the server
- Handles serialized input
- Participates in request processing
React2Shell didn’t introduce that shift. It simply forced teams to confront it.
Exploitation in the Wild and Cryptomining
Once the vulnerability became public, exploitation followed almost immediately.
Cloud providers and security researchers quickly began reporting real-world attacks, many of them opportunistic rather than targeted.
Compromised systems showed:
- Cryptocurrency miners consuming CPU and memory- malicious software that forces servers to generate cryptocurrency for attackers
- Backdoors dropped for persistence— hidden access paths attackers can reuse
- Proxy tooling used to relay traffic
- Follow-on activity typical of opportunistic attackers
In several reported cases, teams redeployed servers repeatedly, only to be reinfected. That pattern revealed the core issue.
The problem wasn’t cleanup. The vulnerable runtime was still in place.
Layered defenses helped, but they could not compensate for an unpatched core dependency.
đ The Technical Deep Dive for Security Engineers
At a high level, React2Shell was enabled by how React Server Components serialize and deserialize data using the React Flight protocol. Attackers were able to abuse that processing path to reach server-side execution, and in Next.js the same path could be triggered through request routing behavior tied to server actions.
For the full protocol-level breakdown, exploitation path, and mitigation details, read Darktrace’s technical analysis end to end.
The Frontend/Backend Boundary Is Gone
React2Shell clarified something that had been evolving quietly for years.
If your frontend framework:
- Runs on the server
- Accepts serialized input-structured data sent between client and server, such as JSON
- Executes during request handling
Then it deserves the same operational scrutiny as any backend service.
This is not a failure of frontend engineering. It is the natural consequence of powerful abstractions becoming production infrastructure.
Modern frameworks trade explicit boundaries for speed and developer experience. That tradeoff doesn’t remove responsibility, it relocates it.
What Teams Needed to Do Immediately
As guidance emerged, response patterns converged across organizations. Teams that moved quickly followed the same playbook.
1. Identify exposure
- Confirm the use of React Server components.
- Verify whether Next.js App Router is enabled
- Check indirect usage via dependencies.
2. Patch and redeploy
-
- Upgrade React Server DOM packages to 19.0.3, 19.1.4, or 19.2.3
- Upgrade Next.js based on your release line:
- 13.x / 14.x: upgrade to 14.2.35
- 15.0.x: upgrade to 15.0.5+
- 15.1.x: upgrade to 15.1.9+
- 15.2.x: upgrade to 15.2.6+
- 15.3.x: upgrade to 15.3.6+
- 15.4.x: upgrade to 15.4.8+
- 15.5.x: upgrade to 15.5.7+
- 16.x: upgrade to 16.0.7+
-
- Redeploy applications after upgrading, Restarting the application so the fixed version is actually running
3. Assume post-exploitation
- Rotate secrets where appropriate
- Review logs and runtime behavior
- Monitor for abnormal resource usage
4. Treat framework upgrades as production changes.
Framework updates affect runtime behavior. They are not cosmetic.
The Bigger Takeaway
React2Shell did not break trust in React. It revealed how much trust modern stacks already carry by default.
The real shift isn’t “patch faster.” It’s recognizing that framework behavior is production infrastructure, and treating it with the same discipline applied to APIs, authentication, and deployments.
Every ecosystem balances:
- Velocity vs visibility
- Abstraction vs control
- Convenience vs explicit boundaries
There is no perfectly safe stack, only well-understood ones.
Teams that handled this incident best were not the ones with the most tools. They were the ones that understood what executed where, and could respond deliberately.
Conclusion
React2Shell spread quickly not because it was sophisticated, but because it aligned with how modern frameworks are built and deployed.
If you run React Server Components or the Next.js App Router in production, treat this like any other runtime incident: patch, redeploy, and verify you weren’t already affected.
And going forward, apply the same rule everywhere: if it runs on the server, it deserves server-grade discipline.