CVE-2026-71316: Nuxt SSR Payload Cache Cross-User Information Disclosure
Nuxt 4.x cached pages stored each user's SSR data in a shared server-side cache keyed only by URL path, letting any visitor fetch another user's private page data with a plain HTTP GET.

The problem
Pages covered by cache, swr, or isr route rules in Nuxt 4.4.0-4.5.0 caused the renderer to write the full SSR payload into a shared cache:nuxt:payload storage entry keyed only by URL path. No session cookie, Authorization header, or cache.varies dimension was included in the cache key.
Once any authenticated user warmed a protected page, a later GET /<page>/_payload.json from a different user or an unauthenticated client was served the cached entry without route middleware or page guards running again. The leaked payload contains everything loaded via useFetch / useAsyncData for that route, including profile data, tenant context, billing details, and token-like values.
The HTML response was correctly varied; only the extracted payload endpoint was affected.
Proof of concept
A working proof-of-concept for CVE-2026-71316 in nuxt, with the exact payload below.
# Step 1: authenticated user (or crawler) warms the cached page
GET /dashboard HTTP/1.1
Host: target.example.com
Cookie: session=<valid-session-token>
# Step 2: unauthenticated attacker retrieves the cached SSR payload
GET /dashboard/_payload.json HTTP/1.1
Host: target.example.com
# Response (no auth required) -- contains the first user's full SSR state:
# {"data":{"me":{"id":1,"email":"victim@example.com","plan":"enterprise",...},...}}The root cause is a missing import.meta.prerender gate on payload-cache reads and writes, introduced in PR #34410 when runtime payload extraction was extended to cached routes in the 4.x line. In 3.x the same code path was guarded by import.meta.prerender, so writes only happened during static prerendering where all users share the same public content.
In 4.4.0-4.5.0 that guard was dropped, making the cache active at runtime. Because the storage key was the URL path alone (CWE-524: Use of Cache Containing Sensitive Information), the payload written for user A was returned verbatim to user B with zero authorization check (CWE-862: Missing Authorization).
The cache.varies option had no effect because the payload cache ignored it entirely.
The fix
Upgrade to nuxt@4.5.1. The patch (commit ac9b41a) re-adds the import.meta.prerender gate so payload-cache reads and writes are limited to build-time prerendering only. At runtime, /_payload.json requests go through the full render pipeline, re-running route middleware and page guards.
Immediate workarounds if you cannot upgrade right now: set experimental.payloadExtraction: false in nuxt.config.ts (the standalone /_payload.json endpoint returns 404; pages still serve an inline payload), or block /**/_payload.json at your CDN or reverse proxy for authenticated routes.
After upgrading, purge any CDN or edge cache that may already hold a leaked payload.
Related research
- high · 7.5CVE-2026-71321CVE-2026-71321: Nuxt Island Endpoint Unauthenticated CPU Exhaustion (DoS)
- high · 7.5CVE-2026-71314CVE-2026-71314: Nuxt Unauthenticated DoS via Unbounded v-for Expansion in Island Rendering
- high · 8.2CVE-2026-71315CVE-2026-71315: Nuxt appMiddleware Auth Bypass via Mixed-Case Route Rule Keys
- highCVE-2026-70475CVE-2026-70475: Flowise Missing Authorization on Execution Update Endpoint