October 2026 CVE of the Month: The Next.js RCE Behind "Not Affected" (CVE-2026-75604)

Vercel's August 25 advisory scoped this month's pick in one line: "Linux and macOS are not affected by this issue." That's true, and most Next.js teams really are fine. The ones that aren't are running it on Windows, and that one line makes them easy to close out with everyone else.

There was a second way to miss it. CVE-2026-75604 was public for a week before its CVE record was published, and for two weeks before the advisory database that dependency scanners read picked it up.

What the CVE record says

Next.js is a React framework for building full-stack web applications. From 13.4.0 until 15.5.24 and 16.3.3, Next.js applications using Pages Router or App Router without Cache Components on Windows-hosted servers do not consistently escape backslashes in route segments before constructing incremental-cache paths. In packages/next/src/shared/lib/router/utils/escape-path-delimiters.ts and packages/next/src/server/lib/incremental-cache/file-system-cache.ts, a remote request can supply encoded Windows path separators that traverse outside the intended cache root and expose private build data, including the server-reference-manifest encryption key. Disclosure of that key can enable remote code execution in the affected application. This issue is fixed in versions 15.5.24 and 16.3.3.

Vercel disclosed CVE-2026-75604 on August 25, 2026, and the CVE record was published September 1, 2026.

At a glance

Empirical Foundation percentile
98th
Empirical Foundation score
0.918
CVSS Base Score
9.0 (v3.1)
EPSS
0.023 (82nd percentile)
Exploitation observed (Empirical telemetry)
Yes (most recent September 24, 2026)
CISA KEV
Not listed
Public exploit code
1 Metasploit module
Vendor
Vercel
Product
Next.js
Attack vector / complexity
Network / High
Privileges / user interaction
None / None

Why CVE-2026-75604 matters

  • The Empirical Foundation model places it in the 98th percentile of all scored CVEs.

  • Empirical's exploitation telemetry shows in-the-wild exploitation within the last 7 days (most recent activity September 24, 2026). This signal comes from our own sensor network.

  • Public exploit code exists: 1 Metasploit module.

Next.js is among the most widely deployed React frameworks, and most of it runs on Linux, including everything hosted on Vercel. The exception is apps self-hosted on Windows Server, usually behind IIS. CyCognito, which tracks internet-facing exposure, calls that a minority pattern inherited from older .NET estates, spread fairly evenly across sectors.

Even on Windows, the bug needs a specific setup. The app has to use both the Pages Router and the App Router with Cache Components off, and keep its incremental cache in the default on-disk location. (The CVE description quoted above says "or." Vercel's advisory and the public Metasploit module require both.) The Metasploit module also needs a dynamic Pages Router route using ISR and a dynamic cached App Router route.

When all of that lines up, one unescaped backslash is enough. An encoded ..%5C in a route segment walks out of the cache folder to server-reference-manifest.json, which holds the key Next.js uses to encrypt the values a Server Action carries between browser and server. With that key an attacker can forge those values without logging in. The Metasploit module turns it into a shell as the Node.js process, as long as the app has at least one Server Action that captures a form field in a closure. CVSS rates attack complexity High. The advisory doesn't say why, but that stack of conditions is the likely reason.

Bottom line

Don't close this on the vendor's "Linux and macOS are not affected" line alone. Close it on evidence of where the app actually runs. If an affected app ran on Windows, rotate the Server Actions key after you patch, whether you pinned it or not. Upgrading alone may not change it.

For its first week, CVE-2026-75604 was Reserved but Public (RBP): the ID was public in Vercel's advisory, but the CVE record had not been published. The CNA Rules set a 72-hour target for publishing once an ID is public. This one took seven days, a lag common enough that the Program has a name for it. Tools that key on published CVE records, NVD and EPSS among them, had nothing to attach to until September 1. The GitHub Advisory Database, which Dependabot, npm audit, and OSV read, listed it on September 8. We opened a record the day after the advisory and were scoring it the day after that.

DateWhat happened
August 17CVE ID reserved
August 25Vercel's repository advisory cites the ID publicly
August 26Our record for the CVE opens, from Vercel's release notes and a public proof-of-concept repository (Empirical data)
August 27The Foundation model scores it for the first time (Empirical data)
September 1CVE record and NVD entry published
September 8GitHub Advisory Database and OSV list it

If your intake waits for the NVD entry, this is the case for changing it. Open tickets from vendor advisories as soon as they cite a CVE ID, carry the GHSA ID alongside it so dependency and host findings merge into one ticket, and recheck scope when the record publishes. Here the record says "or" where the advisory says "both."

News coverage stopped at the patch. The late-August stories, The Hacker News on August 27 among them, reported no exploitation, and no outlet we found has revisited it.

Our score moved anyway. After an opening run at the 14th percentile, the Foundation model held the CVE between the 47th and 60th percentiles into early September, then jumped to the 94th on September 9 with no exploitation in our data. Our sensor network saw activity against it on September 18, the first we had recorded. By the next scoring run, on September 19, the underlying score had nearly doubled, from 0.53 on September 16 to 0.96. It peaked at the 99th percentile on September 25 and sits at the 98th as of this writing.

The scoping line makes that signal easy to miss. Since September 8, dependency scanners flag this CVE in every repository that pins an affected Next.js version, whatever operating system the app ships to. Faced with a long list of those findings, a team can reasonably bulk-close them as "Linux, not affected." The person closing the ticket knows the package version. They often don't know which server the build lands on.

Vercel's advisory does not address key rotation, so key rotation is our recommendation. The Next.js docs say a new Server Actions key is generated for each build. In the code, the key is cached in .next/cache/.rscinfo and reused for up to 14 days, so a rebuild that keeps that folder can keep the old key. Teams running more than one server are told to pin the key with NEXT_SERVER_ACTIONS_ENCRYPTION_KEY, which bakes it into the build, and a pinned key survives any upgrade. On an affected Windows app, assume the key leaked either way.

EPSS ranks this CVE above most, and it is not on the CISA KEV list. Our exploitation signal comes from one sensor source, and with a public Metasploit module out there, some of that activity may be testing rather than intrusion.

Mitigation status

Next.js lists no workaround. Scope first, block while you patch, then clean up.

1. Scope before you close anything

  • Close a finding as not affected only with evidence that no runtime for that app, production or otherwise, is Windows: a deployment manifest, a container base image, or host inventory. The version string in the repository is not evidence.

  • If the app shares a pinned Server Actions key with any Windows deployment, keep it open until step 4 is done, even if it runs on Linux.

  • On Windows, an app is in scope on an affected version if it uses both the Pages Router and the App Router with Cache Components off. Treat those as critical. output: 'standalone' builds use the same default cache and are not exempt.

  • The public exploit also needs a dynamic ISR route in the Pages Router and a dynamic cached route in the App Router. Their absence lowers urgency but does not rule the app out.

  • Check next.config.js for a custom cacheHandler (Redis, S3, and similar). The flaw is in the default filesystem cache, so an app that routes its incremental cache elsewhere should not reach the vulnerable path. The advisory does not state this carve-out, so confirm it per app.

  • To find Windows hosts, look for node.exe running next start, IIS sites that proxy to Node (HttpPlatformHandler, iisnode, or ARR), Windows-based App Service plans on a Node stack, and Windows containers.

  • Tenable plugin 342568 is a local version check for Windows hosts, run through a Nessus Agent or a credentialed scan. It confirms the installed version but does not test the router or cache conditions, and it cannot see hosts outside scanner scope.

2. Block the pattern while you patch

  • At your WAF or reverse proxy, block request paths containing %5C or %255C in any letter case, or a literal backslash, checking the raw path and again after one round of decoding. Scope the rule to the path, not the query string, and test it against legitimate traffic before you enforce it.

  • Fastly Next-Gen WAF customers can enable Fastly's virtual patch for CVE-2026-75604.

  • Keep the rule until the upgrade reaches every affected app (for 13.x and 14.x, until the migration ships).

3. Upgrade and redeploy

  • Upgrade to 15.5.24 or 16.3.3 at minimum. Prefer the current releases, 15.5.26 and 16.3.6.

  • Version 16.3.6 also fixes a separate ImageResponse RCE (GHSA-vcvr-r3jv-pc5j) in 16.2 and later.

  • Before rebuilding, delete .next/cache/.rscinfo (or the whole .next folder, plus any CI cache of .next/cache) so the build generates a new key. Then rebuild and redeploy every affected app.

  • The advisory lists no patched 13.x or 14.x release. Moving those apps to 15.5.24 or later is a framework migration that will not fit in a patch window. File the SLA exception now. Until the migration ships, the WAF rule is your control; where you can, also move the app off Windows or onto a custom cacheHandler.

4. Rotate the key after the fix is live

  • Rotate only once the fixed build is deployed. A vulnerable app exposes a new key the same way it exposed the old one.

  • If NEXT_SERVER_ACTIONS_ENCRYPTION_KEY was set, generate a new key (for example openssl rand -base64 32), set it in the build environment, delete .next/cache/.rscinfo, rebuild once, and deploy that single build to every instance in every environment that used the old key, including Linux ones. The key is embedded at build time, so setting it on running instances does nothing.

  • If the key was not pinned, the clean rebuild in step 3 generates a new one.

  • If you find signs of exploitation, also rotate secrets in files the Node.js process could read, such as .env files and connection strings in web.config.

5. Hunt from August 25 onward

  • Search IIS and proxy logs for the backslash patterns above in route segments, especially under /_next/data/ and against cached routes.

  • Look for a POST that invokes a Server Action, either with a Next-Action header or with multipart form fields named $ACTION_REF_ or $ACTION_ID_. Do not key detection on the header alone.

  • If a traversal request succeeded and the key was pinned, treat Server Action POSTs from any source as suspect until the day you rotate. A stolen key can be replayed later from a different address.

  • Watch for node.exe spawning cmd.exe or powershell.exe.


Next
Next

Where to start: The maturity path from static scoring to prediction