← All posts
·7 min read·GuardLayer

React2Shell in Next.js: which versions are safe?

Next.jsCVEReact Server ComponentsDependenciesSupabase

React2Shell (CVE-2025-55182, tracked for Next.js as CVE-2025-66478) is an unauthenticated remote code execution bug in React Server Components, rated CVSS 10.0. Next.js 15.x, 16.x and 14.3 canaries using the App Router are affected; 13.x, 14.x stable and Pages Router apps are not. Fix it by upgrading to the latest patch in your release line, then rotate every secret the server could read, starting with your Supabase service role key.

React and Vercel disclosed it on 3 December 2025. It was found by Lachlan Davidson, and the AWS security team reported exploitation attempts by China state-nexus threat groups within hours of disclosure. Ten months later "react2shell next version" still shows up in autocomplete, which suggests plenty of people still aren't sure whether their pinned release is affected. This post covers the version check, the fix, and the step most write-ups leave out: what a Supabase app has to rotate afterwards.

Is my Next.js version vulnerable to React2Shell?

Your app is vulnerable if it runs the App Router on Next.js 15.0.0 through 16.0.6, or on 14.3.0-canary.77 or a later canary, below the patched release for its line. The Next.js advisory lists these fixed versions:

Your lineFixed in
15.0.x15.0.5
15.1.x15.1.9
15.2.x15.2.6
15.3.x15.3.6
15.4.x15.4.8
15.5.x15.5.7
16.0.x16.0.7 (Vercel's bulletin now says 16.0.10, see below)
14.3 canary ≥ .77downgrade to next@14

The same advisory says "Next.js 13.x, Next.js 14.x stable, Pages Router applications, and the Edge Runtime are not affected." That covers React2Shell only. Next.js 14 is no longer maintained, so it doesn't get fixes for anything disclosed later. "Not affected by React2Shell" doesn't mean "safe to leave alone".

The underlying bug lives in React's react-server-dom-webpack, -parcel and -turbopack packages, versions 19.0, 19.1.0, 19.1.1 and 19.2.0. Next.js vendors its own copy of those packages, so bumping react in your package.json does nothing for you. Only the next version counts.

"I don't use Server Actions" doesn't get you off the hook

This is the most common wrong reason people give for skipping the patch. The React advisory rules it out:

"Even if your app does not implement any React Server Function endpoints it may still be vulnerable if your app supports React Server Components."

The flaw is in how the server decodes RSC protocol payloads. Every App Router app speaks that protocol, whether or not you wrote a single "use server" function. If you have an app/ directory and a vulnerable next, you're exposed.

How do I fix React2Shell?

Upgrade next. You can't configure your way out of this one. The advisory says "There is no workaround—upgrading to a patched version is required." Vercel's own bulletin is equally frank about its firewall: "WAF rules cannot guarantee protection against all possible variants of an attack."

Vercel ships an interactive fixer that checks your version and bumps it:

npx fix-react2shell-next

Or do it yourself and go past the minimum:

npm install next@latest   # or the latest patch in your major
npm ls next               # confirm what actually resolved

The minimum patch is only enough for the first CVE. On 11 December 2025, React disclosed follow-up bugs in the same code: CVE-2025-55183 (source code exposure) and CVE-2025-55184 and CVE-2025-67779 (denial of service). A fourth DoS, CVE-2026-23864, followed in January 2026. That's why Vercel's table now points 16.0.x at 16.0.10 instead of 16.0.7. Next.js has also shipped several more security releases during 2026. So "patched for React2Shell" and "patched" are different claims, and only the second one matters. Track the latest release in your major, as covered in how known-vulnerable dependencies slip past review.

Patched isn't the same as clean: rotate your secrets

RCE means an attacker ran code inside your server process, and your server process holds process.env. Next.js didn't hedge on this:

"If your application was online and unpatched as of December 4th, 2025 at 1:00 PM PT, we strongly encourage you to rotate any secrets it uses, starting with your most critical ones."

In a Next.js + Supabase app, the most critical one is easy to pick. Row Level Security protects your data from the publishable (anon) key, but it does nothing against the service role key, which bypasses every policy. A service role key read out of process.env gives the attacker full read and write access to every table, long after you've patched the bug that leaked it. Rotate in this order:

  1. The Supabase secret key. On the new key format, create a fresh sb_secret_... key, deploy it, then delete the old one. On a legacy service_role JWT, move to the new keys and deactivate the legacy ones in the dashboard. Supabase says it is deprecating the legacy anon and service_role keys by the end of 2026 anyway. Publishable vs secret keys walks through the swap.
  2. The database password behind any DATABASE_URL or direct Postgres connection string an ORM uses.
  3. Everything else with write power: Stripe secret and webhook signing secrets, email provider keys, LLM API keys, OAuth client secrets.

You don't need to rotate the publishable/anon key for this. It was public to begin with.

What a scan of the manifest shows

Here's a typical Supabase starter that was pinned in mid-2025 and never updated:

{
  "name": "my-saas",
  "private": true,
  "dependencies": {
    "next": "15.3.2",
    "react": "19.1.0",
    "react-dom": "19.1.0",
    "@supabase/ssr": "^0.6.1"
  }
}
guardlayer scan · package.jsonLive engine output
Passed with warnings
92/100 · A
  • Warningpackage.json:5

    Dependency with a known advisory

    Upgrade to the patched version and run npm audit to confirm the advisory is resolved.

To be precise about what that finding says: GuardLayer's dependency rule compares next against the current patched floor, not the React2Shell floor. That's why the message names the newer 2026 advisories and asks for a much later version than 15.3.6. It's also why the finding is correct: any next that clears today's floor has cleared React2Shell long ago. What no static scan can tell you is whether you were exploited while you were exposed. That question belongs to your logs and your secret rotation, not to a manifest.

One more limit. The rule reads the version written in package.json, and a caret range like ^15.3.2 may have resolved to something newer in your lockfile. npm ls next reports the version you actually ship.

A 60-second self-check

# 1. What version is actually installed?
npm ls next

# 2. Are you on the App Router (the affected surface)?
ls -d app src/app 2>/dev/null

# 3. Let Vercel's fixer check and bump it
npx fix-react2shell-next

If step 1 shows a 15.x or 16.x release below the latest patch in its line, and step 2 finds an app/ directory, upgrade today. If the app was live and unpatched on 4 December 2025, work through the rotation list above as well. And while you're in package.json, remember that React2Shell wasn't the only critical Next.js bug in 2025. CVE-2025-29927 bypassed middleware auth entirely, and it was fixed by the same "just upgrade" advice.

FAQ

Is Next.js 14 affected by React2Shell? Next.js 14.x stable releases are not. Canary releases from 14.3.0-canary.77 onward are, and the advisory tells you to downgrade those to the latest stable next@14. Next.js 14 no longer receives security fixes, though, so plan the upgrade to 15 or 16 regardless.

Are Pages Router apps affected? No. The advisory limits the impact to apps using React Server Components through the App Router. A Pages Router-only app isn't affected, and neither is code on the Edge Runtime.

What's the difference between CVE-2025-55182 and CVE-2025-66478? CVE-2025-55182 is the upstream React vulnerability in the RSC packages. CVE-2025-66478 is the Next.js advisory tracking its downstream impact, since Next.js bundles its own copy of those packages. It's one bug with two identifiers, and in a Next.js app the fix is the same: upgrade next.

Does upgrading react and react-dom fix it? Not in a Next.js app. The vulnerable code is in the react-server-dom-* packages, and Next.js ships its own vendored copy. Only upgrading next replaces it.

Does Vercel's firewall protect me? Partially. Vercel deployed WAF rules against known exploits, but its own bulletin says those rules "cannot guarantee protection against all possible variants of an attack." Self-hosted apps don't get those rules at all. Upgrading is the only fix.

Do I need to rotate my Supabase anon key? No. The anon/publishable key is designed to be public and relies on RLS. Rotate the service role or secret key, the database password, and any other secret the server process could read.

Catch this before it ships — free

Scan your files for this and 35 other Next.js + Supabase issues, with the exact fix inline. Connect GitHub and GuardLayer checks every push too — free on public repos.

No signup, no card. Raw files aren’t kept; only the report is saved.

Keep reading

A Solvion project — see also Reglog — EU AI Act changelog, Proceedly, Solenna and Solvion Solutions.