GitHub Advisoryadvisory · npm

GHSA-hg3f-28rg-4jxj Nuxt's route middleware is not enforced when rendering `.server.vue` pages via `/__nuxt_island/page_*`

MEDIUM Published 2026-05-29 Modified 2026-07-08 Official page ↗
Aliases
CVE-2026-47200
Ecosystem
npm
Packages
nuxt, @nuxt/nitro-server
Severity
Moderate
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Weaknesses
CWE-284, CWE-288
Reviewed
2026-05-29

Affected packages

• npm nuxt: >= 3.11.0, < 3.21.6 → fixed in 3.21.6 • npm @nuxt/nitro-server: >= 3.20.0, < 3.21.6 → fixed in 3.21.6 • npm @nuxt/nitro-server: >= 4.2.0, < 4.4.6 → fixed in 4.4.6 • npm nuxt: >= 4.0.0-alpha.1, < 4.4.6 → fixed in 4.4.6

Description

Summary When `experimental.componentIslands` is enabled (default in Nuxt 4), any `.server.vue` file under `pages/` is automatically registered as a server island under the key `page_` and exposed via the `/__nuxt_island/:name` endpoint. Until this fix, requests through that endpoint rendered the page component directly via the SSR renderer without instantiating Vue Router, which meant route middleware declared on the page (including `definePageMeta({ middleware })`) did not run. For Nuxt applications that gate a `.server.vue` *page* behind route middleware as their sole auth check, an unauthenticated attacker could bypass that check by requesting `/__nuxt_island/page__` directly and receiving the server-rendered HTML. Affected configurations All three conditions must hold for an application to be vulnerable: 1. `experimental.componentIslands` is enabled (the default in Nuxt 4; opt-in in Nuxt 3). 2. The application defines one or more `.server.vue` files under `pages/`, registering them as routed pages. 3. Authentication / authorization for at least one such page is enforced solely via route middleware (`middleware/*.ts` referenced from `definePageMeta`), without a server-side check inside the page or its data layer. Applications that enforce auth inside the island's own data layer (server-only API routes, `useRequestEvent` + manual session checks, etc.) were not affected. The general "route middleware does not run for non-page island *components*" behaviour is documented and unchanged; this advisory concerns the `.server.vue` *page* case specifically, where running middleware is the user's clear expectation. Details • Build (`packages/nuxt/src/components/templates.ts`): `.server.vue` pages are registered as island components with `page_` prefix, making them addressable through `/__nuxt_island/page__`. • Runtime (`packages/nitro-server/src/runtime/handlers/island.ts`): the handler resolves the requested island component and renders it via `renderer.renderToString(ssrContext)`. The Vue Router plugin previously short-circuited middleware execution whenever `ssrContext.islandContext` was set. • The two paths interact so that route middleware declared on the source page never runs. Proof of concept Given a page `app/pages/secret.server.vue`: ```vue definePageMeta({ middleware: 'auth' }) SECRET DATA ``` with `middleware/auth.ts` blocking unauthenticated access: ```bash Direct page request: blocked by middleware curl -i http://localhost:3000/secret -> 403 / redirect, depending on the middleware Island request: middleware did not run before this fix curl -i 'http://localhost:3000/__nuxt_island/page_secret_anyhash' -> 200 OK, body includes SECRET DATA ``` Patches Patched in `[email protected]` and `[email protected]` by #35092. The Vue Router plugin now runs middleware and redirect handling for `page_*` islands (i.e. islands that originate from `.server.vue` files in `pages/`). The island handler propagates middleware-issued responses (`~renderResponse`), and a new `beforeResolve` guard returns HTTP 400 when the requested `page_` does not match the route component the URL resolves to. Non-page island components are unaffected - they continue to render without route middleware, by design. Workarounds If you cannot upgrade immediately: • Enforce authentication inside the `.server.vue` page itself, not via route middleware. Read the session from `useRequestEvent()` and `throw createError({ statusCode: 401 })` (or redirect) before returning data. This is the recommended pattern for islands regardless of this advisory. • Disable `experimental.componentIslands` if your app does not use the feature. • If your app must keep route-middleware-only auth, gate the `/__nuxt_island/page_*` URL prefix at your reverse proxy or in a server middleware.

Related

Alias · CVE (1)

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

Weakness · CWE (2)

  • CWE-284 Improper Access Control weakness
  • CWE-288 Authentication Bypass Using an Alternate Path or Channel weakness

References