Next.js incremental cache path traversal to RCE: CVE-2026-75604

One unescaped backslash turns the incremental cache into arbitrary file read and write on Windows, and the leaked Server Action encryption key forges a request that walks a React Flight property chain to Function.

Overview

Field Detail
CVE CVE-2026-75604
CVSS 9.0 (Critical)
CWE CWE-22 path traversal
Affected 13.4.0 to 15.5.23; 16.0.0 to 16.3.2
Fixed in 15.5.24 / 16.3.3
Disclosed August 2026
Exploited in the wild Four public exploits plus a Metasploit module

The flaw, disclosed by the security firm Fortbridge, carries a hard condition: it only holds on a Windows filesystem. The application has to run on Windows, use Pages Router or App Router, and leave Cache Components disabled.

How it was found

The audit covered path construction for the incremental cache. Next.js sanitises cache path segments through a routing helper called escapePathDelimiters, which escapes /, # and ? but misses the backslash entirely.

On Linux or macOS a backslash is an ordinary character. On Windows it is equivalent to a forward slash, a path separator. With a percent-encoded backslash (%5C) inside a route segment, path.join() escapes the expected cache root while constructing the cache file path.

Worse, the traversal applies to both cache reads and writes: it can read any file on the server and write to any path. With both directions available, the flaw stops being information disclosure and becomes potential execution.

Reproduction

Everything below is for authorised security testing on an isolated Windows lab machine.

Prepare an affected version, then create a Server Action and a cache route as documented. The important part is that the action treats user input as a callable value, and it is where the chain lands:

'use server';
export async function processUserInput(boundFn: any, input: string) {
  return boundFn(input)();
}

Step one: read the encryption key through traversal. Repeat ..%5C in the request path to escape the cache root and point at .next/server/server-reference-manifest.json, which stores the key protecting Server Action bound arguments:

traversal = "..%5C" * 8
url = f"{TARGET}/app-cache/{traversal}.next/server/server-reference-manifest.json"

Step two: forge a Server Action. With the encryptionKey in hand, the bound arguments can be encrypted and rebuilt offline. The route in uses a React Flight property chain: constructor.constructor resolves all the way to Function, so a forged bound value can be a function object rather than data.

Step three: deliver it. POST the forged arguments with the Next-Action header. The server decrypts them, the Server Action invokes the closure binding, and the code runs. Against a fully configured target the Metasploit module automates the whole sequence:

msf > use windows/http/nextjs_unauth_rce_cve_2026_75604
msf exploit(...) > set APP_ROUTER app-cache
msf exploit(...) > run

It works through fingerprinting, Build ID retrieval, manifest disclosure, discovery of an available Server Action, encryption of the bound arguments, and the forged request.

Fix

The fixed releases escape backslashes in cache path segments and force the resolved path inside the cache root:

npm install next@15.5.24   # 15.x line
npm install next@16.3.3    # 16.x line

Rotate any key the traversal could have exposed immediately after upgrading, especially Server Action keys that were pinned and reused across builds. Upgrading without rotating leaves a leaked value valid.

There is no configuration-only fix. If upgrading is not immediate, put the application behind a WAF or reverse proxy, block request paths containing %5C or ..%5C at the network layer, and restrict access from untrusted sources. Moving the deployment to Linux removes the platform condition but is not a substitute for the patch.

For detection, look for anomalous paths containing ..%5C in web logs, unexpected child process creation, and suspicious file writes.

Verdict

This is a platform-specific flaw whose root cause is inconsistent handling of path separators across platforms; the / versus \ divide remains a classic source of traversal. The chain it demonstrates is equally typical: traversal, key disclosure, forged authentication, RCE.

What makes it urgent is the barrier to entry. At disclosure there were four confirmed public exploitation tools, including a Metasploit module and several Python frameworks. Next.js users on Windows should check the version first and rotate the key second.

← Back to all posts

Comments

…