---
id: "GHSA-hf59-9xwc-2g4p"
page: "https://infrastack.ai/live/GHSA-hf59-9xwc-2g4p"
kind: "vulnerability"
aliases: ["GHSA-hf59-9xwc-2g4p"]
title: "Colliding island props can share one `/__nuxt_island` path (incomplete fix for CVE-2026-46342)"
severity: "low"
cvss: 3.1
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "nuxt", "fixed": ["4.6.4"], "affected": ">= 4.4.6, < 4.6.4", "ecosystem": "npm"}, {"name": "nuxt", "fixed": [], "affected": ">= 3.21.6, < 4.0.0", "ecosystem": "npm"}, {"name": "@nuxt/nitro-server", "fixed": ["4.6.4"], "affected": ">= 4.4.6, < 4.6.4", "ecosystem": "npm"}, {"name": "@nuxt/nitro-server", "fixed": [], "affected": ">= 3.21.6, < 4.0.0", "ecosystem": "npm"}]
ecosystems: ["npm"]
tags: ["cdn", "cwe-116", "cwe-349", "nitro", "nuxt", "package", "self-hosted", "ssr"]
not_affected_if: ["no-server-islands", "no-user-string-props", "query-aware-cache", "static-export-no-user-links"]
published_at: "2026-11-02T20:59:56+00:00"
first_seen_at: "2026-11-09T22:53:16+00:00"
updated_at: "2026-11-09T22:57:27+00:00"
sources: [{"source": "ghsa-repo", "url": "https://github.com/nuxt/nuxt/security/advisories/GHSA-hf59-9xwc-2g4p", "first_seen_at": "2026-11-09T22:53:16+00:00"}]
exploit_sources: []
---

# Colliding island props can share one `/__nuxt_island` path (incomplete fix for CVE-2026-46342)

Link for people: https://infrastack.ai/live/GHSA-hf59-9xwc-2g4p (this .md is for agents)

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.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- npm:nuxt affected >= 4.4.6, < 4.6.4 fixed 4.6.4
- npm:nuxt affected >= 3.21.6, < 4.0.0 fixed no fixed version listed
- npm:@nuxt/nitro-server affected >= 4.4.6, < 4.6.4 fixed 4.6.4
- npm:@nuxt/nitro-server affected >= 3.21.6, < 4.0.0 fixed no fixed version listed

## How to check

- Check the installed Nuxt version with `npx nuxt --version` or the `nuxt` entry in `package.json` and `package-lock.json`.
- Check `@nuxt/nitro-server` in the lockfile for a version at or above `4.6.4`.
- Look for `<NuxtIsland>` or server components in the app, and for island props that take user-supplied strings.
- Check whether a CDN or reverse proxy caches `/__nuxt_island/*` by path without the query string.

## Fix

- `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 3 has reached end of life and will not receive a fix; upgrade to Nuxt 4.

## Timeline

- 2026-11-09T22:53:16+00:00 ghsa-repo https://github.com/nuxt/nuxt/security/advisories/GHSA-hf59-9xwc-2g4p

## Documents

- [advisory] Maintainer's advisory: github.com https://github.com/nuxt/nuxt/security/advisories/GHSA-hf59-9xwc-2g4p

## From the sources

### Summary

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.

### Impact

For example, these two prop objects serialize identically and share one island path:

```js
{ 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.
- **Path-keyed shared caches.** A CDN or reverse proxy that caches `/__nuxt_island/*` by path only, ignoring the query, can be primed with the colliding response.

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.

### Patches

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.

### Workarounds

- Ensure any intermediary cache keys `/__nuxt_island/*` on the full query string, not on the path alone.
- Treat island props as untrusted input and do not pass them to `v-html` or other HTML sinks without sanitisation.
- When prerendering, avoid including user-submitted links to `/__nuxt_island/` in crawled pages, for example by excluding that prefix with `nitro.prerender.ignore`:

```ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      ignore: [route => route.startsWith('/__nuxt_island/') && route.includes('?')],
    },
  },
})
```

### Credits

Thanks to rat5ak for reporting this issue.

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
