React2Shell is no longer a theoretical RCE. Attackers began scanning and exploiting exposed apps the same day the bug went public, and defenders have been racing since. If you’re using React Server Components (RSC) via frameworks like Next.js, this week is about three things: patch fast, prove you’re clean, and keep watch. This guide gives you the precise versions to install, a practical evidence trail for auditors and clients, and a monitoring plan you can actually run.
What changed since last week?
Timeline matters here. On December 3, 2025, the React team disclosed a critical RCE in the RSC protocol (CVE‑2025‑55182). Within hours, mass scanning and exploitation were observed in the wild. A week later, on December 11, two more RSC issues were published: a high‑severity denial‑of‑service (CVE‑2025‑55184) and a medium‑severity source code exposure (CVE‑2025‑55183). Next.js shipped coordinated patches on December 11 across supported release lines. If you only patched the first CVE, you’re not finished—install the December 11 fixes as well.
Here’s the thing: attackers aren’t waiting for you to schedule a sprint. We’ve seen opportunistic cryptominers, credential grabbers, and stealthier persistence playbooks on compromised hosts. Treat this as an incident even if you’ve just patched.
React2Shell: who’s actually vulnerable?
If your app supports React Server Components, assume exposure until proven otherwise. The upstream React packages affected by the RCE were react‑server‑dom‑webpack, react‑server‑dom‑parcel, and react‑server‑dom‑turbopack (19.0, 19.1.0, 19.1.1, 19.2.0). Fixes shipped as 19.0.1, 19.1.2, and 19.2.1. Downstream frameworks that implement RSC—including Next.js—were impacted and issued their own advisories and patched versions.
For Next.js specifically, the December 11 security update lists the patched versions by line. Use the right target for your branch, not “latest” blindly:
• 14.x → 14.2.35
• 15.0.x → 15.0.7
• 15.1.x → 15.1.11
• 15.2.x → 15.2.8
• 15.3.x → 15.3.8
• 15.4.x → 15.4.10
• 15.5.x → 15.5.9
• 16.0.x → 16.0.10
• Canary lines: use the specified canary builds from the advisory
Pages Router apps aren’t affected by the RSC bugs, but teams frequently mix routers or carry stale dependencies in monorepos. Don’t assume immunity—verify your dependency tree and deployment artifact.
Your 72‑hour plan: patch, prove, monitor
You’re balancing speed and assurance. Ship the patch in hours, not days, but leave an evidence trail you can hand to clients, legal, or the board. Here’s a tight plan you can run between now and the weekend.
1) Patch deterministically
Lock exact versions so CI, staging, and prod match byte‑for‑byte. For Next.js, upgrade to the patched release in your line:
• npm install [email protected] (14.x)
• npm install [email protected] (15.0.x)
• npm install [email protected] (15.1.x)
• npm install [email protected] (15.2.x)
• npm install [email protected] (15.3.x)
• npm install [email protected] (15.4.x)
• npm install [email protected] (15.5.x)
• npm install [email protected] (16.0.x)
If you’re unsure where your estate sits, run the maintainer‑provided CLI in each app and workspace:
• npx fix-react2shell-next
For upstream React packages in custom stacks, pin to react‑server‑dom‑webpack 19.0.1/19.1.2/19.2.1 (matching your minor) and rebuild.
2) Prove you’re patched (and clean)
Patching is table stakes. The gap is proof. Build a short, auditable bundle:
• Dependency evidence: attach a lockfile diff highlighting upgrades to the patched versions and a package manager “why”/“explain” output showing no transitive downgrades.
• Build provenance: capture build IDs or attestations (SLSA‑style if you have them) tying the commit SHA to the artifact deployed to each environment.
• Environment inventory: export container image digests, AMIs, or server checksums; record the rollout timestamp per region.
• Negative assertions: show that known malicious files, processes, and services were not found during the sweep (see the monitoring section for concrete IOCs to check).
• Secret hygiene: if your app was internet‑exposed and unpatched on or after December 3, rotate high‑value secrets (DB, API keys, cloud creds). Document rotation windows and validations.
Package this as a single change request in your ticketing system. If you sell to enterprises, share a brief customer note that outlines the versions you installed and the dates fully rolled out. If you need a template, our earlier breakdown on how to patch, prove, and prevent after React2Shell includes a ready‑to‑adapt outline.
3) Monitor and hunt for intrusions
You’ll want coverage at the edge, on the host, and in your app logs. Prioritize internet‑exposed services first.
Edge indicators:
• Spikes in 404/500s against RSC endpoints, odd User‑Agents, or unusual POST bodies to routes that shouldn’t accept POST.
• Bursts of requests shortly after December 3 and continuing through December 11—common windows for automated exploitation.
Host indicators:
• Unexpected Node or shell children spawned by your web process (e.g., /bin/sh under node, or node writing files to /tmp).
• New or modified files in /tmp/, /var/tmp/, or app‑writable directories; suspicious systemd services or cron jobs created recently.
• Outbound connections to unfamiliar IPs or dynamic DNS hosts from your app containers or instances.
App signals:
• Log entries deserializing unexpected payloads or errors in server function handlers.
• Sudden CPU saturation without a corresponding traffic spike (cryptomining hallmark).
• Suspicious access to configuration files like ~/.aws/credentials from the app user.
Minimum viable hunt (works in most Linux containers/hosts):
• ps -eo pid,ppid,cmd,%cpu --sort=-%cpu | head -n 15
• find /tmp -type f -mtime -10 -maxdepth 1
• systemctl list-units --type=service --state=running | grep -i node
• crontab -l; ls -la /etc/cron.*
• lsof -nPi | grep -E "(node|next)"
If anything looks off, snapshot the instance, isolate it from the network, and redeploy from a known‑good image. Don’t try to clean a live, compromised host in place.
People also ask
Is the Pages Router affected?
Next.js Pages Router apps aren’t directly impacted by the RSC bugs, but many repos mix App Router features, share server utilities, or carry the vulnerable react‑server‑dom packages as transitive dependencies. Confirm with your lockfile and production SBOM rather than relying on framework lore.
Do we need to rotate secrets?
If your app was reachable on the public internet and unpatched at any point after December 3, yes—treat secret rotation as mandatory. Start with cloud credentials and database passwords, then high‑value API tokens. Rotation plus tighter IAM scopes reduces residual blast radius if an intrusion preceded your patch. Our clients often ask for proof of rotation; include timestamps and new key IDs in your evidence bundle.
What if we can’t upgrade React 19 today?
If you’re on a custom stack and can’t bump immediately, seatbelt the perimeter: restrict access to RSC endpoints behind auth, rate limit them, and consider temporary WAF rules to block patterns you’re seeing in logs. That’s buying time, not a fix. Schedule the package upgrade and full redeploy within 48 hours. If you’re on Next.js, the framework patches are the fastest path—use them.
How do we validate no backdoors remain?
Rebuild every internet‑facing app from source with pinned dependencies; redeploy to fresh instances or containers; run a file integrity check on writable paths; and compare network egress before and after. If you find persistence (cron, systemd, rc files), treat it as a confirmed incident and follow your IR plan. If you don’t have one, our week‑two React2Shell checklist includes a concise IR sequence you can adapt.
Gotchas that bite in production
Zero‑downtime rollouts can hide drift. If you deploy via blue‑green or canaries, make sure the autoscaler isn’t quietly keeping old nodes alive. Force recycle the entire pool and check that every pod or VM is running an image built after your patch. Likewise, layer‑cached Docker builds can inadvertently reuse a vulnerable node_modules layer—bust the cache or multi‑stage your dependency install with a lockfile hash as the cache key.
Another common miss: proxies. If your API gateway or CDN routes traffic to legacy paths that still hit RSC endpoints, your shiny patched monolith won’t help the forgotten microservice quietly serving traffic in a corner VPC. Inventory by DNS and TLS certs, not just Git repos.
Finally, don’t forget observability. Backfill dashboards to November 29 so you can correlate odd spikes around disclosure dates. If you detect anomalous activity, link the finding to the deployment timeline—this is gold during post‑mortems and external communications.
What managed platforms changed—and what didn’t
Hosting providers and cloud vendors rolled out mitigations to blunt trivial exploitation, but those stopgaps were never meant to be your long‑term defense. Whether you deploy on Vercel, Netlify, Cloudflare, or your own Kubernetes cluster on AWS, the responsibility to upgrade packages and rebuild images is still yours. Managed shields reduce noise and buy you a window; they don’t patch your codebase, rotate your secrets, or close persistence on compromised hosts.
A practical checklist you can paste into your runbook
Use this as your one‑page task list, then attach the artifacts to your change record.
• Confirm exposure: grep your lockfile for react‑server‑dom‑* and verify your Next.js version.
• Pin patches: upgrade to the per‑line Next.js release above or the fixed React package versions.
• Rebuild from scratch: bust Docker caches; produce a fresh SBOM and artifact digest.
• Roll out progressively: canary to 5–10%, watch errors/latency, then complete the rollout; recycle all old instances.
• Evidence bundle: lockfile diff, build SHA, image digest, rollout timestamps per environment.
• Hunt for IOCs: processes, files, services, and outbound connections listed earlier; save results.
• Rotate secrets: cloud creds, DB passwords, API tokens; re‑deploy with new values.
• Tighten blast radius: least‑privilege IAM for app roles; restrict egress to required domains.
• Update playbooks: add RSC hardening steps and vulnerability SLAs to engineering runbooks.
• Communicate: send a short customer note with versions applied and verification steps taken.
Data you can share with stakeholders
Stakeholders rarely want a deep dive; they want clarity. Anchor on dates and versions: December 3 (RCE disclosure), December 11 (DoS and source exposure updates; Next.js patch drops), and your own rollout times. List the exact versions installed (e.g., Next.js 15.3.8 in production as of December 16, 02:00 UTC), the number of services updated, and whether any anomalies were observed during the hunt. If the app was publicly exposed before patching, note which secrets were rotated and when. Keep this to one page and attach the longer evidence for those who need it.
Related deep dives from our team
If you want a play‑by‑play with scripts and IR templates, start here:
• Our field notes on the Next.js December 11 security update and the exact fixes you need.
• A pragmatic, security‑lead view in React2Shell aftershocks: patch, prove, prevent.
• A week‑two update that adds new CVEs and triage steps: Patch RCE, fix new RSC CVEs.
If your team needs help triaging or hardening, see our security and engineering services.
What to do next
• Today: confirm whether any production workload still runs a vulnerable RSC stack; if yes, patch immediately and begin the evidence bundle.
• Within 72 hours: complete the hunt and secret rotation for exposed apps; recycle all infrastructure; publish your internal and customer notes.
• This sprint: add a pre‑prod dependency gate for security‑advisory‑driven upgrades; ship minimal RSC hardening (auth at the edge, rate limits, sane timeouts).
Zooming out, React2Shell is a reminder to treat framework upgrades like backups: boring, frequent, and automated. The teams who sailed through this week had a clear dependency policy, reproducible builds, and a roll‑forward habit. Everyone else can use this moment to close the gap. Ship the patches, prove the state, and keep watching.