Skip to main content

Nuxt CVE-2026-46342

| EUVDEUVD-2026-36418 LOW
Cross-site Scripting (XSS) (CWE-79)
2026-05-19 https://github.com/nuxt/nuxt GHSA-g8wj-3cr3-6w7v
2.3
CVSS 4.0 · Vendor: https://github.com/nuxt/nuxt

Severity by source

Vendor (https://github.com/nuxt/nuxt) PRIMARY
2.3 LOW
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Primary rating from Vendor (https://github.com/nuxt/nuxt) · only source for this CVE.

CVSS VectorVendor: https://github.com/nuxt/nuxt

CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
P
Scope
X

Lifecycle Timeline

3
CVSS changed
Jun 12, 2026 - 14:22 NVD
2.3 (LOW)
Source Code Evidence Fetched
May 19, 2026 - 20:34 vuln.today
Analysis Generated
May 19, 2026 - 20:34 vuln.today

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 1 npm packages depend on @nuxt/nitro-server (1 direct, 0 indirect)

Ecosystem-wide dependent count for version 3.20.0.

DescriptionCVE.org

Summary

The /__nuxt_island/* endpoint accepts attacker-controlled props query/body parameters and renders any island component without verifying that the URL-resident hash (<Name>_<hashId>.json) was actually issued for those inputs by <NuxtIsland>. The hash is computed and embedded client-side but never validated server-side, so the same path can return materially different responses depending on the query.

Island components are documented as rendering independently of route context - page middleware does not apply to them, and they are intentionally cacheable as a function of their props. This advisory does not treat that contract as a vulnerability. It treats the absence of a binding between the URL the cache keys on and the response served at that URL as one.

Impact

In applications where a CDN or reverse-proxy in front of the app caches /__nuxt_island/* keyed by path only (ignoring query) - a documented misconfiguration class, see GHSA-jvhm-gjrh-3h93 - an attacker can prime the cache for a path with their own choice of props, and subsequent users requesting the same path receive the attacker's rendered HTML rather than the response intended for them. The cache entry persists until normal expiry.

Where the affected island has any prop flowing into an unsafe HTML sink in application code (v-html, innerHTML, a third-party renderer treating a prop as HTML), this becomes stored XSS in the embedding page's origin until the cache entry expires. HttpOnly cookies remain out of reach but anything else in the origin (other cookies, in-origin requests, DOM state) is reachable by the injected script.

Preconditions:

  • experimental.componentIslands enabled (or the default 'auto' with at least one server / island component in the app).
  • A shared intermediary cache (CDN, reverse-proxy, edge cache) keyed on path only.
  • For the XSS pivot specifically: an application-authored island that puts a prop through an unsafe HTML sink.

Without the second precondition, the response shape is per-request and unaffected. Without the third, the worst case is content-swap / inert HTML injection rather than script execution.

Patches

Patched in nuxt@4.4.6 and nuxt@3.21.6 by #35077. The island handler now recomputes the expected hashId from (name, props, context) using the same ohash function <NuxtIsland> already uses to embed the hash in the URL, and rejects requests (HTTP 400) whose URL-resident hash does not match. The response is now a pure function of the request path: a path-keyed shared cache returns the correct response to every requester for that path, and an attacker cannot synthesise a path whose hash matches arbitrary props.

Workarounds

For users unable to upgrade immediately:

  • Ensure any intermediary cache keys /__nuxt_island/* on the full query string, not on the path alone. This is the recommended configuration regardless.
  • Audit application-authored islands for props flowing into v-html / innerHTML / similar HTML sinks; treat island props as untrusted user input.

Note on island authentication

> [!IMPORTANT] > It's important to remember that route middleware does not run when rendering island components, and islands cannot rely on routing-layer auth. Applications gating sensitive data behind page middleware should enforce that auth inside the island's own data layer (server-only routes, useRequestEvent + manual session checks, etc.) rather than relying on the embedding page's middleware - this was true before this advisory and remains true after it.

A separate advisory addresses *.server.vue *pages* registered as page_<routeName> islands, where the documented "middleware doesn't run for islands" contract collides with the page's own definePageMeta({ middleware }) declaration in a way that constitutes a genuine bug rather than documented behaviour.

AnalysisAI

Cache poisoning via the /__nuxt_island/* endpoint in Nuxt allows an attacker to prime a shared CDN or reverse-proxy cache with attacker-controlled rendered HTML, causing subsequent users requesting the same island path to receive the poisoned response. Affected are nuxt 3.1.0-3.21.5 and 4.0.0-alpha.1-4.4.5, as well as @nuxt/nitro-server 3.20.0-3.21.5 and 4.2.0-4.4.5. When any island component passes a prop into an unsafe HTML sink (v-html, innerHTML), the cache poisoning escalates to stored XSS persisting in the application's origin until cache expiry, exposing non-HttpOnly cookies, in-origin requests, and DOM state. No public exploit identified at time of analysis.

Technical ContextAI

Nuxt's Component Islands feature renders server-side components via /__nuxt_island/<Name>_<hashId>.json, where <hashId> is computed client-side by <NuxtIsland> using the ohash library over the tuple (name, props, context, source). Prior to the fix, the server-side island handler in @nuxt/nitro-server accepted the hashId from the URL but never recomputed or validated it against the actual props submitted in the query string or request body. This broke the assumed binding between the cache key (URL path containing the hash) and the rendered content's inputs. The root cause maps to CWE-79 (Improper Neutralization of Input During Web Page Generation): attacker-supplied prop values reach HTML output without the URL-level integrity check that was assumed to gate access. The fix in PR #35077 introduces a shared island-hash.ts module used by both <NuxtIsland> (client) and the island handler (server); the handler now calls computeIslandHash(name, filteredProps, clientContext, undefined) and rejects any request whose URL-resident hashId does not match with HTTP 400, making the response a pure function of the request path.

RemediationAI

Vendor-released patch: upgrade to nuxt@3.21.6 (3.x branch) or nuxt@4.4.6 (4.x branch) and the corresponding @nuxt/nitro-server versions, as shipped via PR #35077 (https://github.com/nuxt/nuxt/pull/35077). For users unable to upgrade immediately, configure any CDN, reverse-proxy, or edge cache to key /__nuxt_island/* responses on the full query string rather than the path alone; this prevents cache poisoning regardless of the server-side hash validation gap, though it may reduce cache hit rates for legitimate shared renders. As an independent hardening measure, audit all application-authored island components for props flowing into v-html, innerHTML, or third-party HTML-rendering sinks, and sanitize or remove such patterns - this eliminates the XSS escalation path even when the caching precondition exists, limiting the worst case to inert content substitution. The vendor advisory notes that route middleware does not run for island components; gating sensitive island data must be enforced within the island's own data layer (server-only routes, useRequestEvent with manual session checks), independent of this fix.

Share

CVE-2026-46342 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy