CVE-2026-75604
Path traversal no cache ISR do Next.js contorna o Proxy e permite RCE no Windows
Uma divergência entre a rota autorizada e o caminho usado pelo FileSystemCache permitia ler artefatos protegidos e, em uma cadeia específica, executar código sem autenticação.

- Componente
- packages/next/src/server/lib/incremental-cache/file-system-cache.ts
- Versões afetadas
- Next.js >= 13.4 e < 15.5.24; >= 16.0 e < 16.3.3
- Versões corrigidas
- Next.js 15.5.24 e 16.3.3
- Advisory oficial
- GitHub Security Advisory
Resumo
A CVE-2026-75604 é uma vulnerabilidade de path traversal no cache em disco do Next.js em servidores Windows. Uma rota com ..%5C podia passar pelo Proxy como uma URL pública e, depois da decodificação, virar um caminho com ..\ dentro do FileSystemCache.
No Windows, a barra invertida é um separador de diretório. O cache podia então sair do diretório associado à rota pública e alcançar outro artefato em .next/server.
Essa primitiva sustentava duas cadeias:
- um
Proxy bypass, no qual uma requisição anônima lia HTML e RSC de uma página estática protegida; - uma cadeia entre App Router, Pages Router e Server Actions que expunha o
server-reference-manifest.jsone podia terminar em RCE sem autenticação.
O advisory oficial atribuiu CVSS 9.0 e classificou a complexidade como alta. A falha não atingia todo projeto Next.js no Windows: a cadeia completa dependia de uma combinação específica de routers, cache e Server Action.
Condições para a cadeia RCE
O impacto de RCE exigia:
- servidor Next.js executado nativamente sobre um filesystem Windows;
- Pages Router e App Router na mesma aplicação;
- Cache Components desativado;
- cache padrão em disco;
- uma rota ISR dinâmica no Pages Router;
- uma rota armazenada pelo App Router;
- uma Server Action compatível que capturasse um valor externo em sua closure.
Linux e macOS não interpretam \ como separador de diretório. A mesma chave não produz o traversal nesses sistemas.
Causa raiz
O Proxy e o cache não tomavam a decisão sobre a mesma identidade de rota.
Considere esta requisição:
GET /posts/..%5Cpremium
O Proxy recebia o pathname ainda codificado e o tratava como uma instância da rota pública /posts/[slug]. Mais tarde, o processamento da rota chamava decodePathParams(). O %5C se tornava uma barra invertida antes de o valor chegar ao cache.
O FileSystemCache combinava esse pathname com o diretório base. No Windows, o resultado era normalizado pelo filesystem:
.next\server\app\posts\..\premium.html
=> .next\server\app\premium.html
Assim, a autorização havia sido feita sobre /posts/..%5Cpremium, enquanto a leitura ou gravação usava o artefato de /premium.
O patch corrigiu os dois lados do problema: passou a escapar barras invertidas durante a formação do caminho e adicionou uma verificação para impedir que o destino resolvido saísse da raiz permitida do cache.
Cadeia de Proxy bypass
O primeiro reporte de @rafabd1 demonstrou o problema com uma página /premium gerada no build e protegida por uma sessão no Proxy. A rota /posts/[slug] era pública e usava ISR.
O acesso anônimo direto era bloqueado:
GET /premium
HTTP/1.1 307 Temporary Redirect
Location: /login
A variante com traversal, porém, fazia o cache devolver o artefato já existente da página protegida:
GET /posts/..%5Cpremium
HTTP/1.1 200 OK
Nenhuma vítima precisava aquecer o cache. O conteúdo de /premium já existia porque a página havia sido prerenderizada durante o build.
Se a entrada estivesse stale, a mesma chave também podia iniciar uma revalidação em background e substituir o conteúdo protegido pela renderização da rota pública. A falha afetava, portanto, a confidencialidade do conteúdo e a integridade dos artefatos ISR.
Cadeia RCE entre os dois routers
A cadeia RCE usava a diferença entre os formatos de cache dos dois routers.
Pages Router: <chave>.html + <chave>.json
App Router: <chave>.html + <chave>.rsc + <chave>.meta
O App Router podia ser levado a criar um arquivo com o nome-base server-reference-manifest dentro de .next/server. O manifesto privado original já existia no mesmo diretório:
.next/server/server-reference-manifest.html <- criado via traversal
.next/server/server-reference-manifest.json <- manifesto privado existente
Uma segunda requisição pelo Pages Router encontrava esse par .html e .json e o aceitava como uma entrada ISR válida. O JSON retornado ao cliente era, na verdade, o server-reference-manifest.json, que contém IDs de Server Actions e a encryptionKey usada para proteger valores capturados por closures.
O vazamento da chave não executa código por si só. A etapa final exige uma Server Action compatível, com um valor externo capturado. O atacante pode forjar o payload cifrado da closure para substituir a referência legítima pelo construtor JavaScript Function. Quando a action usa o valor capturado, o código fornecido pelo atacante roda no processo do servidor.
Essa dependência explica a métrica de alta complexidade do advisory. O exploit precisa reconhecer rotas adequadas, construir o alias entre os dois formatos de cache e encontrar uma action que ofereça a primitiva necessária.
PoC público
Após a publicação do advisory e do patch, @rafabd1 reconstruiu a cadeia completa e publicou um PoC parametrizado para CVE-2026-75604. O repositório inclui um alvo local em Next.js 16.2.11 e permite informar as rotas de cache, o caminho da Server Action e o comando usado na validação.

A demonstração acima usa o mesmo PoC público. Ele deve ser executado somente em sistemas próprios ou com autorização explícita.
Versões afetadas e correção
O advisory lista estes intervalos:
Next.js >= 13.4 e < 15.5.24
Next.js >= 16.0 e < 16.3.3
As versões corrigidas são 15.5.24 e 16.3.3. Não há workaround geral para aplicações afetadas hospedadas no Windows. A recomendação é atualizar e refazer o deploy:
npm install next@15.5.24
ou:
npm install next@16.3.3
Também é importante verificar o sistema operacional do processo que serve a aplicação. O ambiente usado para desenvolver ou gerar o build não determina o filesystem do servidor em produção.
Timeline e atribuição
- 21 de julho de 2026, 21:19 UTC:
@rafabd1reportou à Vercel opath traversalnoFileSystemCachee demonstrou a cadeia de Proxy bypass. - 21 de julho de 2026, 21:54 UTC: um segundo pesquisador reportou a cadeia de RCE baseada na mesma primitiva, cerca de 35 minutos depois.
- 26 de julho de 2026:
@rafabd1enviou detalhes adicionais sobre o cenário de ataque e o impacto do bypass. - 25 de agosto de 2026: a Vercel publicou a GHSA-p293-qw3h-jr36, a CVE-2026-75604 e as versões corrigidas.
Uma explicação mais extensa da cadeia está disponível no writeup original.