NUXT · GHSA-hf59-9xwc-2g4p · Package
FIX → 4.6.4
Nuxt server islands hash their props to pick a URL path, and the hash can collide for different prop objects, so a crafted request can get another island's path to render attacker-chosen content. Where a prop reaches an unsafe HTML sink, this can run script in the site's origin; otherwise the impact is content substitution.
first public Nov 2, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Applications that use Nuxt server components or <NuxtIsland> with island props that carry attacker-influenced strings, such as stored comments or profile fields. Impact is highest when prerendering with user-submitted links present, or when a path-keyed CDN or reverse proxy caches island responses. Applications that do not use islands, or where no island receives attacker-controlled string props, are not affected. Nuxt 3 has no fix because it is end of life.
Not affected if no-server-islands, no-user-string-props, query-aware-cache, static-export-no-user-links
Who cares cdn, nitro, nuxt, self-hosted, ssr
npx nuxt --version or the nuxt entry in and .The fix for CVE-2026-46342 (GHSA-g8wj-3cr3-6w7v) binds each /__nuxt_island/<Name>_<hash>.json path to its props by hashing the (name, props, context, source) tuple. That hash was computed over ohash's serialization, which does not escape quotes inside strings or delimiters inside keys, so two different prop objects can produce the same hash. A request with crafted props can therefore pass validation for another island's path and render different content at that path.
For example, these two prop objects serialize identically and share one island path:
{ html: '', note: '<img src=x onerror="alert(1)">' }
{ html: '\',note:\'<img src=x onerror="alert(1)">' }
This reopens the scenarios described in GHSA-g8wj-3cr3-6w7v:
nuxt generate / prerendering. Nuxt caches prerendered island responses by path. If the crawler reaches a link to the colliding URL (for example in user-submitted content included in the build) before it renders the page that uses the legitimate props, the colliding response is written into the generated page.Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
package.jsonpackage-lock.json@nuxt/nitro-server in the lockfile for a version at or above 4.6.4.<NuxtIsland> or server components in the app, and for island props that take user-supplied strings./__nuxt_island/* by path without the query string.Upgrade to 4.6.4
nuxt 4.6.4 (for the 4.x line, affected >= 4.4.6, < 4.6.4)@nuxt/nitro-server 4.6.4 (for the 4.x line, affected >= 4.4.6, < 4.6.4)/__nuxt_island/*An attacker has to construct props that collide with a specific legitimate tuple, which in practice means at least part of that tuple is a string they control (for example a stored comment or profile field passed as a prop). Where a prop reaches an unsafe HTML sink in the island (v-html, innerHTML, a renderer treating a prop as HTML), the substituted response can execute script in the site's origin. Without such a sink, the impact is content substitution.
Applications are not affected if they do not use server components or <NuxtIsland>, or if no island receives attacker-influenced string props. Server-rendered responses that are not cached by path alone are also unaffected.
Fixed in nuxt@4.6.4 and @nuxt/nitro-server@4.6.4. The island hash is now computed over a canonical JSON encoding of the tuple, in which strings and keys are escaped, so different props can no longer produce the same hash.
Island hashes change as a result. Clients that build island URLs themselves should use the exported getIslandHash rather than hashing with ohash directly.
Nuxt 3 has reached end of life and will not receive a fix. Upgrade to Nuxt 4.
/__nuxt_island/* on the full query string, not on the path alone.v-html or other HTML sinks without sanitisation./__nuxt_island/ in crawled pages, for example by excluding that prefix with nitro.prerender.ignore:export default defineNuxtConfig({
nitro: {
prerender: {
ignore: [route => route.startsWith('/__nuxt_island/') && route.includes('?')],
},
},
})
Thanks to rat5ak for reporting this issue.