GitHub Advisoryadvisory · npm

GHSA-48hr-524c-v5w3 Nuxt: Unauthorized Component Instantiation via Server Island Props

MEDIUM Published 2026-08-05 Modified 2026-08-05 Official page ↗
Aliases
CVE-2026-71318
Ecosystem
npm
Packages
nuxt
Severity
Moderate
CVSS vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
Weaknesses
CWE-20
Reviewed
2026-08-05

Affected packages

• npm nuxt: >= 4.0.0, < 4.5.1 → fixed in 4.5.1 • npm nuxt: >= 3.1.0, < 3.21.10 → fixed in 3.21.10

Description

Impact Nuxt server islands accept props via the `/__nuxt_island/` endpoint. When an application has a server island component that forwards props directly into Vue's dynamic component resolution (``, `resolveDynamicComponent`, or `h()`), an attacker can pass a plain string value (rather than a component definition) to instantiate any globally-registered Vue component or any native HTML element. For example: ```json { "as": "SomeGlobalComponent" } ``` ...resolves and renders `SomeGlobalComponent` if it is globally registered, even though the attacker should only be able to drive props for the island's declared component. Similarly, `{ "as": "iframe" }` renders an `` element. Unlike the primary RCE vector (GHSA-9473-5f9j-94wq), this does not require `vue.runtimeCompiler` to be enabled. A plain string prop is sufficient to trigger component resolution. The `template`/`render` key guard that addresses the RCE vector does not block plain string values. Some component libraries expose a polymorphic `as` / `asChild` prop that forwards its value into ``; `@nuxt/ui` (via `reka-ui`) is a widely used example. An application is affected if such a component receives the attacker-controlled value inside a server island. Note this does not require explicit prop forwarding: island props the island component does not declare fall through as attributes onto its single root element, so an island whose root is a `reka-ui` / `@nuxt/ui` component receives the attacker's `as` value implicitly. Unlike the RCE vector, no `vue.runtimeCompiler` is required, which makes this vector reachable in more configurations. These libraries are not themselves vulnerable; they are noted only because they commonly provide the dynamic-component sink. Installing `@nuxt/ui` does not by itself register any component as a server island: the application must define the island (a `.server.vue` file). Mitigating factors • Exploitation requires a server island component that puts an attacker-controlled value onto a dynamic-component path (``, `resolveDynamicComponent`, `h()`, or a polymorphic `as` / `asChild` prop), either explicitly or via attribute fallthrough when the island's root is such a component. • Reachable components are limited to what is actually in the island app's global registry. In a default pages-enabled app that is `RouterView` and `RouterLink` (both registered globally by the pages router plugin, which runs even in component islands), plus any `components/global/` component and any component a module registers globally. `RouterLink` in particular renders an attacker-influenced `` (and, because an island that declares no props forwards all props, `to` and other `RouterLink` props ride the same fallthrough). Vue built-ins (`Transition`, `KeepAlive`, `Teleport`, `Suspense`) and Nuxt auto-imports (`ClientOnly`, `NuxtLink`, `NuxtPage`, etc.) are NOT in the island app's global registry and cannot be resolved this way; an unresolved name instead renders as a native HTML element (the element-injection half of this issue). • Declaring the props an island accepts, or setting `inheritAttrs: false` on it, prevents an undeclared `as` from falling through to a polymorphic root and neutralizes this vector. • Arbitrary JavaScript execution is not possible through this vector (no `template`/`render` compilation). • Island component names are constrained to the build-time component registry; an attacker cannot resolve arbitrary components. Affected versions Nuxt `>=3.1.0 =4.0.0 ` / `h()` / `resolveDynamicComponent()`, or that forwards it under a different polymorphic prop name, is therefore not covered by the patch and must follow the guidance below. The Nuxt documentation now warns against this. Workarounds Upgrade to `[email protected]` or `[email protected]`. That upgrade also removes the related object-prop RCE (GHSA-9473-5f9j-94wq). In addition, in any version: 1. Do not forward island props into ``, `resolveDynamicComponent`, or `h()`. Map an untrusted discriminator through a closed allowlist of imported component definitions instead of passing the raw prop value. 2. Declare the props an island accepts, or set `inheritAttrs: false` on it, so request input cannot fall through to a polymorphic root component. 3. Avoid registering sensitive components globally that could leak information if instantiated by an attacker.

Related

Alias · CVE (1)

  • CVE-2026-71318 Nuxt is an open-source web development framework for Vue.js. vulnerability

Weakness · CWE (1)

  • CWE-20 Improper Input Validation weakness

References