React2Shell (CVE-2025-55182): 48-Hour Engineering Playbook to Patch, Detect, and Prevent RSC RCE
A critical React Server Components RCE tracked as React2Shell CVE-2025-55182 can enable unauthenticated remote code execution by exploiting how certain RSC packages decode payloads sent to React Server Function endpoints—and your app may still be exposed even if you didn’t explicitly build “server function endpoints,” as long as you support RSC.
This post turns “update now” into an engineering-grade plan you can run in 48 hours: inventory → patch safely → mitigate at the edge → detect → add CI guardrails → validate → produce audit-ready evidence.

Step 1) Fast impact check: confirm whether you’re exposed (15–60 minutes)
1A) Identify vulnerable RSC packages and versions
Per the official advisory, the vulnerable packages are:
react-server-dom-webpackreact-server-dom-parcelreact-server-dom-turbopack
…when installed at 19.0, 19.1.0, 19.1.1, or 19.2.0.
Run these from your app repo:
# npm
npm ls react-server-dom-webpack react-server-dom-parcel react-server-dom-turbopack || true
# yarn
yarn why react-server-dom-webpack || true
yarn why react-server-dom-parcel || true
yarn why react-server-dom-turbopack || true
# pnpm
pnpm why react-server-dom-webpack || true
pnpm why react-server-dom-parcel || true
pnpm why react-server-dom-turbopack || true1B) Quick “RSC / Next.js usage” repo checks
# Next.js presence
cat package.json | sed -n '1,160p' | grep -E '"next"\s*:|"react"\s*:|"react-dom"\s*:' || true
# Heuristic: "use server" appears in some RSC/server-action patterns
rg -n --hidden --glob '!**/node_modules/**' '"use server"' . || true
# Heuristic: RSC-related keywords in code/config
rg -n --hidden --glob '!**/node_modules/**' '(react-server-dom|server components|rsc|flight)' . || true1C) Build artifact + container image checks (what runs in prod)
If you build on CI and deploy containers, scan what you actually ship:
# Check lockfile for the vulnerable packages and versions
rg -n '"react-server-dom-(webpack|parcel|turbopack)"' package-lock.json yarn.lock pnpm-lock.yaml || trueNode script: fail-fast version extraction (package-lock.json)
// scripts/check-react2shell-lockfile.js
// Usage: node scripts/check-react2shell-lockfile.js
const fs = require("fs");
const VULN = new Set(["19.0", "19.1.0", "19.1.1", "19.2.0"]);
const PKGS = [
"react-server-dom-webpack",
"react-server-dom-parcel",
"react-server-dom-turbopack",
];
function readJSON(p) {
return JSON.parse(fs.readFileSync(p, "utf8"));
}
function getPkgVersionFromNpmLock(lock, name) {
// npm v7+ package-lock has "packages" map
const packages = lock.packages || {};
const key = `node_modules/${name}`;
return packages[key]?.version || null;
}
let lockPath = "package-lock.json";
if (!fs.existsSync(lockPath)) {
console.log("OK: no package-lock.json found (skip).");
process.exit(0);
}
const lock = readJSON(lockPath);
let hits = [];
for (const p of PKGS) {
const v = getPkgVersionFromNpmLock(lock, p);
if (v && VULN.has(v)) hits.push({ package: p, version: v });
}
if (hits.length) {
console.error("FAIL: React2Shell (CVE-2025-55182) exposure found:");
for (const h of hits) console.error(`- ${h.package}@${h.version}`);
process.exit(2);
}
console.log("OK: no vulnerable RSC package versions found in package-lock.json");1D) SBOM-based inventory (best for multi-repo orgs)
If you already generate SBOMs (recommended), search them centrally:
# Example (CycloneDX JSON) — grep for package names
rg -n '"name":"react-server-dom-(webpack|parcel|turbopack)"' sbom*.json || trueStep 2) Patch strategy: safe upgrade paths + rollout patterns (2–12 hours)
2A) Patch the vulnerable RSC packages immediately
Fixed versions were introduced in 19.0.1, 19.1.2, and 19.2.1.
If you directly depend on the RSC packages:
npm install react-server-dom-webpack@^19.0.1
# or
npm install react-server-dom-parcel@^19.0.1
# or
npm install react-server-dom-turbopack@^19.0.12B) Next.js safe upgrade paths (patch within your release line)
The official guidance for Next.js is to upgrade to the latest patched version in your release line (examples below).
npm install [email protected] # for 13.3.x, 13.4.x, 13.5.x, 14.x
npm install [email protected] # for 15.0.x
npm install [email protected] # for 15.1.x
npm install [email protected] # for 15.2.x
npm install [email protected] # for 15.3.x
npm install [email protected] # for 15.4.x
npm install [email protected] # for 15.5.x
npm install [email protected] # for 16.0.x2C) Rollout pattern that avoids self-inflicted outages
Recommended order:
- Canary (1–5% traffic)
- Staged deploy (25% → 50% → 100%)
- Rapid rollback pre-tested (helm/argo revert)
Argo Rollouts example (canary + analysis hook):
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: webapp
spec:
replicas: 8
strategy:
canary:
steps:
- setWeight: 5
- pause: { duration: 5m }
- setWeight: 25
- pause: { duration: 10m }
- setWeight: 50
- pause: { duration: 10m }
selector:
matchLabels: { app: webapp }
template:
metadata:
labels: { app: webapp }
spec:
containers:
- name: webapp
image: your-registry/webapp:PATCHED_TAGStep 3) WAF/edge mitigations while patching (deploy in <1 hour)
These are temporary risk reducers, not “the fix.”
3A) Reduce attack surface by request shape controls
At the edge/reverse proxy:
- Restrict HTTP methods (deny unexpected POSTs to routes that don’t need it)
- Set body size limits (block oversized payloads early)
- Rate limit suspicious endpoints
- Require auth for any “server action / function” endpoints (if applicable in your app)
Nginx example (body limits + rate limits):
# http {}
limit_req_zone $binary_remote_addr zone=rsc_rl:10m rate=10r/s;
server {
client_max_body_size 256k;
location / {
# baseline
}
# Apply to endpoints you identify as RSC / server-function entrypoints
location ~* ^/(api|_next|rsc|actions) {
limit_req zone=rsc_rl burst=20 nodelay;
client_max_body_size 128k;
}
}3B) Block obviously risky patterns (careful: avoid false positives)
Start with narrow rules, then widen based on logs:
- POSTs to endpoints that normally only GET
- High-entropy bodies on routes that normally accept small JSON
- Spikes in 4xx/5xx on RSC routes
Step 4) Detection: what to alert on first (same day)
Multiple threat actors have been observed exploiting React2Shell (CVE-2025-55182), so prioritize “blast-radius” detections: suspicious requests, suspicious process behavior, and unexpected egress from app nodes.
4A) App-layer indicators (log-based)
Alert on:
- Sudden spikes in 500s on RSC/server-function routes
- Unusual POST volume to routes that aren’t typically hot
- Requests with very large bodies or abnormal content-types hitting those routes
Elastic/KQL-ish starting points (adapt to your schema):
# 500 spikes on suspected RSC endpoints
url.path:(*rsc* OR *_next* OR *actions* OR *api*) AND http.response.status_code:500
# high request body size (if logged)
event.dataset:nginx.access AND http.request.method:POST AND http.request.body.bytes > 2000004B) Host/container indicators (process spawning)
If your Node/Next process starts spawning shells or download tools, treat it as a red alarm.
Falco rule example (Node spawning shell tools):
- rule: Node process spawns shell
desc: Detect node/next spawning shells or common download tools
condition: >
spawned_process and
(proc.pname in (node, next-server, next) or proc.aname in (node, next-server, next)) and
(proc.name in (sh, bash, dash, zsh, curl, wget))
output: >
Suspicious spawn by %proc.pname -> %proc.name (user=%user.name cmdline=%proc.cmdline)
priority: CRITICAL4C) Network egress indicators (unexpected outbound)
Alert on new outbound destinations from webapp nodes/containers (especially to raw IPs) right after the disclosure window.
Step 5) CI guardrails: pinning + policy checks + emergency patch lane
5A) Dependency pinning / overrides (stop reintroduction)
npm overrides example:
{
"overrides": {
"react-server-dom-webpack": "^19.2.1",
"react-server-dom-parcel": "^19.2.1",
"react-server-dom-turbopack": "^19.2.1"
}
}Yarn resolutions example:
{
"resolutions": {
"react-server-dom-webpack": "^19.2.1",
"react-server-dom-parcel": "^19.2.1",
"react-server-dom-turbopack": "^19.2.1"
}
}5B) Make builds fail if vulnerable versions appear
Add the lockfile checker from Step 1C into CI.
GitHub Actions snippet:
name: security-policy
on:
pull_request:
push:
branches: [ "main" ]
jobs:
block-react2shell:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: node scripts/check-react2shell-lockfile.js5C) “Emergency patch lane” (the operational trick most teams lack)
Create a fast path that:
- runs minimal but critical tests
- requires AppSec + platform approval
- deploys canary automatically
- produces an evidence bundle
Example: PR label gates
on:
pull_request:
types: [labeled]
jobs:
emergency:
if: contains(github.event.pull_request.labels.*.name, 'security-hotfix')
steps:
- run: echo "Run hotfix pipeline (tests + canary deploy + evidence artifacts)"Step 6) Post-patch validation: exploit-resistant + regression-safe (same day)
6A) Verify dependency closure (don’t trust “we upgraded”)
npm ls react-server-dom-webpack react-server-dom-parcel react-server-dom-turbopack
npm ls next6B) Targeted regression tests for RSC routes
If you have Playwright/Cypress, add a smoke test that:
- loads key RSC pages
- exercises server actions (if used)
- checks no new 5xx spikes
Playwright quick smoke example:
import { test, expect } from "@playwright/test";
test("RSC smoke: homepage loads", async ({ page }) => {
const resp = await page.goto("https://staging.example.com/");
expect(resp?.status()).toBeLessThan(500);
await expect(page).toHaveTitle(/.*/);
});6C) Validate mitigations (WAF/rate-limits) behave as intended
Confirm:
- blocked requests return 403/429 (not 500)
- legitimate traffic remains clean
Free Website Vulnerability Scanner tool page

Step 7) Evidence you can reuse: audit-ready artifacts (30–90 minutes)
You want an evidence pack you can attach to a ticket, a change record, or an incident note.
7A) Evidence pack folder structure (copy/paste)
react2shell-cve-2025-55182-evidence/
01-scope-inventory/
02-dependency-diff/
03-sbom/
04-ci-policy-output/
05-deploy-rollout/
06-validation-results/
07-monitoring-detections/
incident-note.md
manifest.json
manifest.sha2567B) Dependency diff capture
git checkout main
git pull
git show --name-only --stat > react2shell_change_summary.txt
# Optional: capture lockfile diff
git diff HEAD~1..HEAD -- package-lock.json yarn.lock pnpm-lock.yaml > lockfile.diff.txt || true7C) Manifest + hashing (script)
cd react2shell-cve-2025-55182-evidence
find . -type f -maxdepth 2 | sort > manifest.txt
sha256sum $(cat manifest.txt) > manifest.sha2567D) Incident note template (short + useful)
# React2Shell (CVE-2025-55182) Response Note
**Summary:** Patched vulnerable RSC components and Next.js release line; deployed staged rollout; added CI guardrails; validated closure.
**Scope:** Repos/apps affected: …
**Risk:** Unauthenticated RCE on servers running vulnerable RSC packages.
**Actions taken:**
- Inventory completed (SBOM + lockfile checks)
- Patch applied (versions + PR links)
- Edge mitigations deployed (rate limit/body limits)
- Detections enabled (process spawning + egress anomalies)
- Validation completed (tests + monitoring)
**Residual risk / exceptions:** …
**Evidence location:** …Step 8) Long-term prevention: stop “critical dependency fire drills”
- High-severity dependency SLA
- Critical/KEV-like: patch in 24–72 hours
- High: 7–14 days
- Medium: 30 days
- Automated routing to engineering on-call
- Alert when SBOM/lockfile contains vulnerable packages
- Auto-create tickets with owners from service catalog
- Standard “compensating controls library”
- Rate-limiting snippets
- Request size guards
- Auth enforcement templates
For a repeatable remediation cadence (and evidence packs auditors trust), model your workflow after our internal sprint playbooks:
- https://www.pentesttesting.com/cisa-kev-remediation-sprint-in-30-days/
- https://www.pentesttesting.com/risk-register-remediation-plan/
Use our free scanner for fast before/after screenshots (recommended)
Sample report page to check Website Vulnerability

Pro tip: take two screenshots (before patch and after patch) and store them in your evidence pack under 06-validation-results/.
Where Pentest Testing Corp helps (security hotfix lane → proof)
If you want this run as a repeatable “security hotfix lane”—including scoping across repos, SBOM-based inventory, safe rollout, and an audit-ready evidence pack—Pentest Testing Corp can support end-to-end:
- https://www.pentesttesting.com/risk-assessment-services/
- https://www.pentesttesting.com/remediation-services/
Related reading (recent):
- https://www.pentesttesting.com/sierra-wireless-airlink-aleos-vulnerability/
- https://www.pentesttesting.com/cisa-kev-remediation-sprint-in-30-days/
- https://www.pentesttesting.com/risk-register-remediation-plan/
🔐 Frequently Asked Questions (FAQs)
Find answers to commonly asked questions about React2Shell CVE-2025-55182 Fix Steps.

