React2Shell (CVE-2025-55182): A Real Incident on Azure App Service and How I Fixed It
A first-hand incident report of attempted React2Shell exploitation against a Next.js 15 + React 19 app hosted on Azure App Service, what we saw, what actually happened under the hood, and exactly how we remediated it.
On December 3, 2025, the React and Vercel teams publicly disclosed CVE-2025-55182, a critical remote code execution vulnerability in React Server Components, nicknamed React2Shell by the security community in reference to the devastating Log4Shell vulnerability of 2021. Within hours, automated exploitation campaigns were already scanning the internet.
I was running Next.js 15.1.7 and React 19.0.0 on Azure App Service, both squarely in the vulnerable range. This is a first-hand account of what I observed, what was actually happening, and how I resolved it.
What Is React2Shell (CVE-2025-55182)?
Before getting into the incident, it helps to understand why this vulnerability is so serious.
The Technical Root Cause
React 19 introduced React Server Components (RSC), which let React components run exclusively on the server. To communicate between server and client components, React implemented an internal serialization format called the Flight protocol, it serializes component trees and data for transmission between server and client.
The vulnerability lies in how the server-side Flight protocol deserializes incoming payloads. When a server receives a specially crafted, malformed payload, it fails to validate the structure correctly. This allows attacker-controlled data to influence server-side execution logic, resulting in arbitrary JavaScript code executing with the full privileges of the server process.
What makes this especially alarming:
- No authentication required, a single crafted HTTP POST request is enough
- Default configurations are vulnerable, a standard
create-next-appproject, built for production, with no custom code, can be exploited - Near-100% reliability, security researchers reported near-perfect success rates in testing
- You don't need to explicitly use Server Actions, simply supporting React Server Components is enough to be exposed
Affected Versions
| Package | Vulnerable | Patched |
|---|---|---|
react / RSC packages | 19.0, 19.1.0, 19.1.1, 19.2.0 | 19.0.1, 19.1.2, 19.2.1+ |
next (App Router) | 15.0.0 – 15.1.8, 16.0.0 – 16.0.6 | 15.1.9, 15.2.6, 15.3.6+ |
Not affected: Next.js Pages Router apps, Edge Runtime, and any app running React 18 or earlier.
My stack, next@15.1.7 + react@19.0.0, was vulnerable on both counts.
Initial Symptoms
The first signs of trouble appeared in the Azure App Service environment:
- Unexpected files appearing in the application directory
- Attempts to execute shell-related scripts from within the app process
- Suspicious binaries associated with cryptomining tools (XMRig)
- Intermittent server restarts accompanied by runtime errors
- A Node.js version mismatch between environments (more on this below)
Despite these indicators, the app continued running, no user data was exposed, and no persistent remote access was established. The activity had all the hallmarks of automated, opportunistic exploitation, not a targeted attack.
What Was Actually Happening
The cryptomining artifacts weren't random. This is a well-documented pattern from the React2Shell exploitation campaigns that started on December 5, 2025, two days after public disclosure.
Security researchers at Google Threat Intelligence Group and Palo Alto's Unit 42 identified campaigns where attackers exploited CVE-2025-55182, then immediately tried to download and execute a shell script (commonly named sex.sh) that installs XMRig, a cryptocurrency miner, and attempts to establish persistence via a new systemd service. This is exactly the class of artifacts I observed.
The exploitation flow looks like this:
Attacker → Crafted HTTP POST to any App Router endpoint
→ RSC Flight protocol deserializes malicious payload
→ Arbitrary server-side code execution
→ wget/curl downloads malicious shell script
→ XMRig miner installed, persistence attempted
Why It Didn't Fully Succeed
Azure App Service's sandbox environment significantly limited what attackers could do even after achieving code execution:
- Reverse shell attempts failed (outbound connections blocked)
- Processes were not running persistently between restarts
- Binary execution permissions were restricted
- Miner payloads couldn't establish the systemd persistence they expected (Windows-based App Service plan)
The incident was attempted exploitation, not a successful compromise. But it was very real, and it was happening.
Investigation
1. Confirming Vulnerability
The first step was confirming my exact versions:
{
"next": "15.1.7",
"react": "^19.0.0",
"react-dom": "^19.0.0"
}Both packages were in the vulnerable range. Running npx fix-react2shell-next (a tool Vercel released to scan monorepos) confirmed the issue and flagged the required upgrade target: next@15.1.9.
2. Investigating the Node.js Version Mismatch
During investigation I also found a Node.js version mismatch: local development used Node.js 20, while Azure Kudu console showed Node.js 18. This was a separate deployment configuration issue, it caused build/runtime inconsistencies but was not the security vulnerability. I resolved it by aligning the runtime in App Service settings, but this was not the root cause of the exploitation attempts.
3. Examining Suspicious Artifacts
Files observed in the deployment directory:
- Empty shell scripts
- Archived binaries
- Mining-related folders
- Files with unexpected executable permissions
These are the typical footprint of the XMRig deployment scripts documented in public threat intelligence reports from this campaign.
Remediation
Step 1: Upgrade Dependencies (Primary Fix)
The only real fix is patching, there is no workaround.
# Update Next.js to the patched version
pnpm add next@15.1.9
# Update React and React DOM to patched versions
pnpm add react@19.0.1 react-dom@19.0.1
# Or use Vercel's automated fix tool
npx fix-react2shell-nextAfter applying the upgrade and redeploying, the exploitation attempts stopped producing results. No new suspicious files appeared. Logs returned to normal.
Important: After patching, Vercel recommends rotating all application secrets (environment variables, API keys, tokens) as a precaution, even if you don't believe secrets were accessed.
Step 2: Harden Azure App Service Access Restrictions
As an additional defense layer, I updated App Service access restrictions:
- Added IP-based access rules to block known malicious scanner ranges
- Restricted access to App Router endpoints where possible
- Enabled Azure's built-in WAF rules for the deployment
Note: WAF rules are a temporary stopgap, not a solution. Attackers can modify payloads to bypass signature-based blocking. The only reliable fix is upgrading your dependencies.
Step 3: Clean Rebuild and Redeployment
Rather than trying to manually clean up suspicious files:
- Removed all existing build artifacts from the deployment
- Deleted and rebuilt
node_modulesfrom scratch - Redeployed from a trusted CI/CD pipeline
This eliminates any uncertainty about leftover artifacts from the exploitation attempts.
Step 4: Environment and Secrets Review
Additional verification steps:
- Reviewed all environment variables for signs of modification
- Confirmed no credentials had been read or exfiltrated
- Verified filesystem permissions
- Monitored outbound connections for any residual beaconing
No signs of persistence or data access were found.
Post-Remediation Check
To verify the fix, you can also check your running version from the browser console on any page of your Next.js app:
next.version
// Should return "15.1.9" or higherOr check via the response headers, patched Next.js versions include updated RSC runtime behavior that rejects malformed Flight protocol payloads.
Outcome
After remediation:
- Application stability fully restored
- No recurring suspicious activity in logs
- Updated dependency chain eliminated the attack surface entirely
- Azure sandbox logging remained clean
The incident was classified as prevented exploitation.
Lessons Learned
1. React2Shell Is Not Theoretical
This wasn't a lab exercise. Exploitation campaigns began within 48 hours of public disclosure. If you were running a vulnerable version of Next.js with App Router on a public-facing server between December 5–10, 2025, you were almost certainly scanned and likely probed.
2. Default Configurations Are Not Safe by Default
The most counterintuitive aspect of CVE-2025-55182 is that you don't need to write any insecure code to be vulnerable. A standard create-next-app project, no custom Server Actions, no special configuration, is vulnerable in its default state if running React 19 and Next.js 15 App Router.
3. WAF Rules Are Not a Substitute for Patching
Cloud providers including Azure, AWS, and Google Cloud all deployed WAF rules to block known exploit patterns. These provide temporary relief, but attackers continually modify payloads to evade signature-based detection. The only reliable fix is upgrading to a patched version.
4. Platform Sandboxing Matters, But Don't Rely on It
Azure App Service's sandbox environment meaningfully limited attacker impact in this incident. Reverse shells failed, miner persistence failed, and process execution was constrained. However, this is defense-in-depth, not a primary control. A less sandboxed environment (bare VPS, Kubernetes with permissive pod security, etc.) would have had a very different outcome.
5. Keep a Dependency Upgrade Cadence
Framework upgrades are not only feature releases. For server-side frameworks especially, minor version bumps frequently include critical security fixes. A process for tracking and promptly applying dependency updates would have eliminated this exposure before exploitation began.
Quick Reference: Am I Vulnerable?
| Condition | Vulnerable? |
|---|---|
| Next.js App Router + React 19.0–19.2.0 | ✅ Yes |
| Next.js 15.0.0 – 15.1.8 | ✅ Yes |
| Next.js Pages Router only | ❌ No |
| Next.js Edge Runtime only | ❌ No |
| React 18 or earlier | ❌ No |
| Next.js 15.1.9+ with React 19.0.1+ | ❌ No (patched) |
Further Reading
- React Security Advisory, Official disclosure
- Vercel React2Shell Bulletin, Patching guide and
fix-react2shell-nexttool - Next.js Security Advisory (CVE-2025-66478), Next.js-specific advisory
- Wiz Research Deep Dive, Technical analysis of the Flight protocol flaw
- Google Threat Intelligence Report, Post-exploitation campaign analysis
- Microsoft Security Blog, Azure-specific guidance
- Palo Alto Unit 42, Exploitation chain breakdown including IOCs
If you maintain a Next.js App Router application, check your package.json now. The fix is a one-line upgrade and a redeploy, and if you were running 15.1.7 or earlier with React 19, you were in the vulnerable window.