CVE-2026-75604
Next.js ISR cache path traversal bypasses Proxy and enables RCE on Windows
A mismatch between the authorized route and the path used by FileSystemCache exposed protected artifacts and, under specific conditions, allowed unauthenticated code execution.

- Component
- packages/next/src/server/lib/incremental-cache/file-system-cache.ts
- Affected versions
- Next.js >= 13.4 and < 15.5.24; >= 16.0 and < 16.3.3
- Fixed versions
- Next.js 15.5.24 and 16.3.3
- Official advisory
- GitHub Security Advisory
Summary
CVE-2026-75604 is a path traversal vulnerability in the Next.js disk cache on Windows servers. A route containing ..%5C could pass through Proxy as a public URL and, after decoding, become a path containing ..\ inside FileSystemCache.
Windows treats a backslash as a directory separator. The cache could therefore leave the directory assigned to the public route and reach another artifact under .next/server.
This primitive supported two exploit chains:
- a Proxy bypass that let an unauthenticated request read the HTML and RSC payload of a protected static page;
- a chain across the App Router, Pages Router, and Server Actions that exposed
server-reference-manifest.jsonand could end in unauthenticated RCE.
The official advisory assigned a CVSS score of 9.0 and rated attack complexity as high. The issue did not affect every Next.js project on Windows. The complete RCE chain required a specific combination of routers, cache behavior, and a Server Action.
Conditions for the RCE chain
RCE required:
- a Next.js server running natively on a Windows filesystem;
- Pages Router and App Router in the same application;
- Cache Components disabled;
- the default filesystem cache;
- a dynamic ISR route in the Pages Router;
- a cached App Router route;
- a compatible Server Action that captured an external value in its closure.
Linux and macOS do not treat \ as a directory separator, so the same cache key does not produce traversal on those systems.
Root cause
Proxy and the cache did not make their decisions over the same route identity.
Consider this request:
GET /posts/..%5Cpremium
Proxy received the encoded pathname and treated it as an instance of the public /posts/[slug] route. Route processing later called decodePathParams(), turning %5C into a backslash before the value reached the cache.
FileSystemCache joined that pathname to its base directory. On Windows, the filesystem normalized the result:
.next\server\app\posts\..\premium.html
=> .next\server\app\premium.html
Authorization had been performed for /posts/..%5Cpremium, while the cache read or wrote the artifact belonging to /premium.
The patch fixed both sides of the problem. It escapes backslashes while forming the cache path and rejects resolved destinations outside the allowed cache root.
Proxy bypass chain
The first report from @rafabd1 demonstrated the flaw with a /premium page generated at build time and protected by a session check in Proxy. /posts/[slug] was public and used ISR.
Direct anonymous access was blocked:
GET /premium
HTTP/1.1 307 Temporary Redirect
Location: /login
The traversal variant made the cache return the existing protected artifact:
GET /posts/..%5Cpremium
HTTP/1.1 200 OK
No victim had to warm the cache. The /premium artifact already existed because the page had been prerendered during the build.
If the entry was stale, the same alias could also start background revalidation and replace the protected content with the public route rendering. The issue therefore affected both confidentiality and the integrity of ISR artifacts.
RCE chain across both routers
The RCE chain used the difference between the cache formats of the two routers.
Pages Router: <key>.html + <key>.json
App Router: <key>.html + <key>.rsc + <key>.meta
The App Router could be made to create an artifact with the basename server-reference-manifest under .next/server. The original private manifest already existed in that directory:
.next/server/server-reference-manifest.html <- created through traversal
.next/server/server-reference-manifest.json <- existing private manifest
A second request through the Pages Router found the .html and .json pair and accepted it as a valid ISR entry. The JSON returned to the client was actually server-reference-manifest.json, which contains Server Action IDs and the encryptionKey used to protect closure-bound values.
Leaking the key does not execute code on its own. The final step needs a compatible Server Action with a captured external value. An attacker can forge the encrypted closure payload and replace the legitimate reference with JavaScript's Function constructor. When the action uses the captured value, attacker-supplied code runs in the server process.
This dependency accounts for the advisory's high attack complexity. Exploitation requires suitable routes, an alias across the two cache formats, and an action that provides the required primitive.
Public PoC
After the advisory and patch became public, @rafabd1 independently reconstructed the full chain and released a parameterized CVE-2026-75604 PoC. The repository includes a local Next.js 16.2.11 target and accepts the cache routes, Server Action path, and validation command as arguments.

The demonstration above uses the same public PoC. Run it only against systems you own or are explicitly authorized to test.
Affected versions and fix
The advisory lists these ranges:
Next.js >= 13.4 and < 15.5.24
Next.js >= 16.0 and < 16.3.3
The fixed versions are 15.5.24 and 16.3.3. There is no general workaround for affected Windows-hosted applications. Upgrade and redeploy:
npm install next@15.5.24
or:
npm install next@16.3.3
Check the operating system of the process serving the application. The machine used for development or build generation does not determine the production server's filesystem.
Timeline and attribution
- July 21, 2026, 21:19 UTC:
@rafabd1reported theFileSystemCachepath traversal to Vercel and demonstrated the Proxy bypass chain. - July 21, 2026, 21:54 UTC: a second researcher reported the RCE chain based on the same primitive, about 35 minutes later.
- July 26, 2026:
@rafabd1provided more detail about the attack scenario and bypass impact. - August 25, 2026: Vercel published GHSA-p293-qw3h-jr36, CVE-2026-75604, and the fixed releases.
A longer explanation of the chain is available in the original writeup.