Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.
Open advisories
25 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
Since `4.6.0`, Nuxt resolves `.` and `..` segments in the request path, including percent-encoded forms such as `%2e`, before rendering a page. Nitro's routing, Nitro's route rules and `server/middleware` see the path with those segments still in place. A request for `/%2e/admin` therefore renders the page at `/admin`, while server-side checks keyed on `/admin` do not apply. Impact An unauthenticated attacker can bypass server-side controls that match on the request path of a page route. `server/middleware` that checks `event.path` (or `event.node.req.url`) is skipped: ```ts export default defineEventHandler((event) => { if (event.path.startsWith('/admin') && !isAuthenticated(event)) { throw createError({ statusCode: 401 }) } }) ``` With this middleware, `/admin` returns 401, but `/%2e/admin`, `/.%2e/admin` and `/x/%2e%2e/admin` reach the middleware with `event.path` set to `/./admin`, `/../admin` and `/x/../admin`, and render `app/pages/admin.vue` along with the data…
Recommended action: Upgrade to 4.6.3 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact useHeadSafe restricts head input to an allowlist of safe tags and attributes. For example, bodyAttrs is limited to class and style, event handler attributes are removed, and <script tags are only kept for JSON types. When useHeadSafe is called inside a server island (a .server.vue component or page, or a component rendered with <NuxtIsland), the island renderer serialises the raw input of every head entry into the island response without the option that marks it as safe input. <NuxtIsland then pushes that input into the page's head as a regular entry, both during server rendering and when hydrating or refetching on the client. As a result, input that useHeadSafe would normally strip (such as bodyAttrs.onload or executable <script content) is rendered into the page. If an application passes user-controlled data to useHeadSafe inside a server island, an attacker who controls that data can achieve stored cross-site scripting on the application's origin. Mitigating factors -…
Recommended action: Upgrade to 4.6.2 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact An application that renders <NuxtLink :to="..." with a value it does not control can be made to render an anchor whose href executes script in the application's origin when clicked. This is an incomplete fix for GHSA-934w-87qh-qr26 (CVE-2026-53722). It only affects applications running without a pages/ directory, where pages resolves to false and Nuxt registers its own router in place of vue-router. Applications using vue-router are not affected. Prefixing javascript: with an ASCII C0 control character, for example %01, meant the value was not recognised as having a protocol. It was classified as an internal route and so never reached the protocol check added in GHSA-934w-87qh-qr26, and the router used for pages: false passed it through to the rendered href unchanged. Browsers strip the leading control character and run the result as a script URL. Both <NuxtLink custom and the default anchor are affected, and the href is present in the server-rendered HTML. Mitigating factors…
Recommended action: Upgrade to 4.6.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Nuxt compared routeRules keys against the raw request path, without decoding percent-encoding, while the router decodes parameters when it resolves a route. A request whose path is percent-encoded can therefore resolve to a page while failing to match the route rule meant to protect it, so the rule's appMiddleware never runs, including during server rendering. Impact For a page served through a dynamic or catch-all route, an attacker can percent-encode a character in the path to skip the rule: Requesting /users/%61dmin still renders app/pages/users/[id].vue with id decoded to admin, but the rule keyed /users/admin does not match, so auth does not run and the server renders and returns the gated page to an unauthenticated visitor. No privileges and no user interaction are required, and only ASCII characters are involved. Purely static ASCII routes are not affected: static segments are matched without decoding, so a request for /%61dmin does not resolve to the page registered…
Recommended action: Upgrade to 4.4.4 or 3.21.4 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact When a Nuxt dev server is bound to a network-reachable interface (for example nuxt dev --host for on-device testing), the default-enabled Chrome DevTools workspace endpoint GET /.well-known/appspecific/com.chrome.devtools.json returns the absolute project root (workspace.root, i.e. rootDir) and a persistent per-project workspace UUID. GHSA-rq7w-g337-39qq added a gate (isLocalDevRequest) intended to restrict this endpoint to local requests, but that gate is header-based: it trusts request metadata rather than the connected peer address. A request with no Sec-Fetch-Site, Origin, and Referer headers (normal for a non-browser client such as curl) is treated as local, and the Host allow-list is compared against the attacker-supplied Host header. As a result, any unauthenticated host that can reach the dev server on the LAN can retrieve the project's absolute filesystem path and workspace UUID, for example with curl -H 'Host: localhost'…
Recommended action: Upgrade to 4.5.1 or 3.21.10 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact The internal island renderer endpoint (/nuxtisland/...) decodes and hashes attacker-controlled request input before it validates the URL-resident hash. An unauthenticated POST /nuxtisland/<name<anything.json with a large JSON body (for example ~4.6 MB / 150k keys) is fully read, destr-parsed, and run through ohash before the request is rejected with a 400. Because Nitro runs on a single event loop, this both wastes CPU on the doomed request and delays every concurrent request. A low request rate is enough to degrade or stall the server. No valid hash and no authentication are required. Patches Fixed in nuxt@4.5.1 and nuxt@3.21.10. The island handler now enforces a raw body-size cap (413) and a JSON nesting-depth cap (400) before parsing or hashing, so oversized or deeply nested input is rejected cheaply. Workarounds Put a small request-body limit in front of /nuxtisland/ at your reverse proxy / edge (islands legitimately send only a compact props payload), or disable server…
Recommended action: Upgrade to 4.5.1 or 3.21.10 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact Nuxt server islands accept props via the /nuxtisland/ endpoint. When vue.runtimeCompiler: true is enabled (off by default) and the application has a server island component that forwards props into Vue's dynamic component resolution (<component :is, resolveDynamicComponent, or h()), an attacker can inject a template key into the island props to achieve server-side remote code execution in the Nitro process. Vue's runtime template compiler compiles and executes the attacker-controlled template in the server process. The same primitive also works on the client side when the runtime compiler is active there, though the server-side path is the primary concern. Some component libraries expose a polymorphic as / asChild prop that forwards its value into <component :is; @nuxt/ui (via reka-ui) is a widely used example. An application is affected if such a component receives the attacker-controlled value, provided vue.runtimeCompiler is also enabled. Note this does not require the…
Recommended action: Upgrade to 4.5.1 or 3.21.10 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact Nuxt server islands accept props via the /nuxtisland/ endpoint. When an application has a server island component that forwards props directly into Vue's dynamic component resolution (<component :is, 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: ...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 <iframe 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…
Recommended action: Upgrade to 4.5.1 or 3.21.10 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact When a page is covered by routeRules cache / swr / isr, Nuxt enables runtime payload extraction and serves /<page/payload.json. On affected versions the renderer stored the SSR payload in the shared cache:nuxt:payload storage under a path-only key (no cookie, authorization, or cache.varies dimension) and, on a later payload request, returned the cached entry before route middleware / page guards ran again. As a result, once any authenticated user warms a protected, cached page, a subsequent GET /<page/payload.json from an unauthenticated client or a different authenticated user receives the first user's payload: the full SSR data for that route, including anything loaded via useFetch / useAsyncData (for example /api/me: profile, tenant, billing, token-like values). The HTML response stays correctly varied and protected; only the extracted payload leaks. Both cross-user (A warms, B receives A) and unauthenticated disclosure are exploitable. cache.varies does not mitigate it,…
Recommended action: Upgrade to 4.5.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact Nuxt matches route rules case-insensitively by default (mirroring vue-router's default sensitive: false routing). The fix for GHSA-mm7m-92g8-7m47 / CVE-2026-53721 lowercased the lookup path before matching route rules, but the route-rule keys compiled into the matcher were left verbatim. As a result, any route rule whose key contains an uppercase character (for example /Admin, /Dashboard/, or the rules Nuxt derives from PascalCase/camelCase page files such as pages/Admin.vue) never matches, because every lookup is folded to lowercase while the key stays mixed-case. vue-router still serves the page case-insensitively, so the page renders with none of its Nuxt route-rule protections applied. The most serious consequence is an authorization bypass: an appMiddleware rule used as an auth gate (routeRules: { '/Admin/dashboard': { appMiddleware: 'auth' } }) is dropped, and /Admin/dashboard, /admin/dashboard, and /ADMIN/dashboard all render the protected page (and its SSR-fetched…
Recommended action: Upgrade to 4.5.1 or 3.21.10 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact An unauthenticated attacker can crash a Nuxt server that renders any island / server component containing a v-for over a prop (for example v-for="n in count" or a <slot v-for). Because the island URL hash is a non-secret digest of the request, the attacker can compute a valid hash for arbitrary props and send the iterated prop as a large integer. The server then expands the v-for to that many nodes during SSR, allocating memory proportional to the attacker's number. Reporter figures: count=8000000 produced a 142.9 MB response; count=40000000 (and items=4000000 on a slot list) produced an out-of-memory crash of the worker from a single ~130-byte request. Both the plain v-for path (Vue's ssrRenderList) and the slot path (vforToArray) are affected. Patches Fixed in nuxt@4.5.1 and nuxt@3.21.10. Island/server-component v-for sources are now clamped to a maximum iteration count (MAXVFORLENGTH = 100000) at the render boundary, covering the plain path, the <slot v-for element, and the…
Recommended action: Upgrade to 4.5.1 or 3.21.10 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact Nuxt's globally registered <NoScript component (from @unhead/vue head components, re-exported by Nuxt) wrote its default-slot content to the innerHTML of the <noscript head tag, bypassing the HTML escaping that {{ }} interpolation normally applies in Vue templates. Applications that placed untrusted, attacker-controllable data inside a <NoScript slot, for example: would emit that value unescaped inside <noscript in the server-rendered HTML. With scripting enabled, the HTML parser treats <noscript content in <head under the "in head noscript" insertion mode: any tag other than link, meta, noframes, or style implicitly closes <noscript and is re-processed in the head. A payload such as <script...</script therefore escapes the element and executes in the document context. Sibling head components (<Style, <Title) were not affected because they already routed slot text through the safe textContent path. Affected versions All currently supported versions of nuxt that ship the…
Recommended action: Upgrade to 4.4.7 or 3.21.7 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
<NuxtLink did not validate the URL scheme of values bound to its to or href props before rendering them into the href attribute of the underlying <a element. When an application binds attacker-controlled input (a query parameter, a CMS field, a user-supplied profile URL) to <NuxtLink :to or :href, the attacker can supply a javascript: or vbscript: URL that is reflected verbatim into the rendered markup. Clicking the link executes the supplied script in the origin of the Nuxt application, resulting in reflected DOM-based cross-site scripting. A data:text/html,... payload reflected through the same sink does not execute in the application's origin but enables a same-tab phishing surface anchored to a legitimate application link. The same value was exposed to consumers of the component's custom slot via the href and route.href props, so applications that re-bind those values to their own anchors were affected identically. Unlike the previously reported navigateTo issue…
Recommended action: Upgrade to 4.4.7 or 3.21.7 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact When running nuxt dev on Linux (Node.js 20+, outside Docker / StackBlitz), Nuxt's internal vite-node IPC server binds to a Linux abstract-namespace Unix socket (\0nuxt-vite-node-<pid-<ts.sock). Abstract sockets have no filesystem inode and therefore no permission bits: any local UID on the host that can read /proc/net/unix can enumerate the socket and connect to it. The IPC server does not perform any peer-credential or shared-secret check before dispatching requests. The module request type passes its moduleId field straight into Vite's SSR fetchModule(), which is not gated by Vite's HTTP-layer server.fs.allow deny-list. A co-resident unprivileged local user can therefore request paths like /home/<dev/project/.env?raw or ~/.ssh/idrsa?raw and read the developer's secrets through the dev server's SSR plugin pipeline. The resolve request type additionally enables filesystem probing. This affects developers running nuxt dev on shared multi-tenant Linux hosts (lab machines, shared…
Recommended action: Upgrade to 4.4.7 or 3.21.7 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact Nuxt looks up routeRules for the current navigation by calling getRouteRules({ path: to.path }) from the page-router plugin and the no-pages router plugin. The compiled routeRules matcher (built on rou3) performs case-sensitive matching, while vue-router is configured with its default sensitive: false and matches paths case-insensitively. The two routers therefore disagree on which rules apply to a given request path: vue-router still matches the page record for /Admin/dashboard, but the routeRules lookup for the same path returns no match. Any appMiddleware declared via routeRules is never added to the middleware set and never runs, on both SSR and client navigations. The same path skips other path-keyed route rules in the same way (ssr, redirect, appLayout, and the prerender / payload hints used client-side). For applications using routeRules with appMiddleware as an authorization gate (a documented pattern), an attacker can flip the case of any static segment in a protected…
Recommended action: Upgrade to 4.4.7 or 3.21.7 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Three weaknesses in Nuxt's client-navigation URL handling, all reachable from documented public APIs (navigateTo and reloadNuxtApp): 1. (CVE-2026-56326) SSR open redirect in navigateTo via path-normalisation bypass. navigateTo decided whether a target was external by inspecting the raw input with hasProtocol(..., { acceptRelative: true }). Inputs such as /..//evil.com, /.//evil.com, /%2e%2e//evil.com, or /app/..//evil.com slipped past that check because they start with /, but WHATWG URL parsing then normalised them to the protocol-relative pathname //evil.com. The normalised value was written to the Location response header and into the <meta http-equiv="refresh" body of the SSR redirect page, so a victim's browser would resolve the redirect cross-origin to the attacker's host. 2. (CVE-2026-56698) Client-side script execution via navigateTo({ open: ... }). The client-side early-open handler called window.open(toPath, ...) without applying the isScriptProtocol check that gates…
Recommended action: Upgrade to 4.4.7 or 3.21.7 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
When running nuxt dev, Nuxt registers an unauthenticated route at /.well-known/appspecific/com.chrome.devtools.json that returns the absolute filesystem path of the project root and a per-project UUID persisted to nodemodules/.cache/nuxt/chrome-workspace.json. The route is enabled by default via experimental.chromeDevtoolsProjectSettings: true. The endpoint exists to let Chrome DevTools' Workspace integration map sources to the developer's local checkout. The handler is registered directly on nitro.options.devHandlers and does not pass through the CORS / origin wrapper that the rest of the dev pipeline uses, so it has no host / origin / Sec-Fetch-Site check of its own. Impact Dev-server only. Production builds do not register the route. Two values are disclosed: - workspace.root: the absolute filesystem path of the project (commonly reveals the OS username and the on-disk project name). - workspace.uuid: a v4 UUID persisted to nodemodules/.cache/nuxt/chrome-workspace.json,…
Recommended action: Upgrade to 4.4.7 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
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<routeName and exposed via the /nuxtisland/: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 /nuxtisland/page<routeName<anyhash 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…
Recommended action: Upgrade to 4.4.6 or 3.21.6 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The /nuxtisland/ 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 /nuxtisland/ keyed by path only (ignoring query) - a documented misconfiguration class, see GHSA-jvhm-gjrh-3h93 - an attacker can prime the cache for a…
Recommended action: Upgrade to 4.4.6 or 3.21.6 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
navigateTo() with external: true generates a server-side HTML redirect body containing a <meta http-equiv="refresh" tag. The destination URL is only sanitized by replacing " with %22, leaving <, , &, and ' unencoded. An attacker who can influence the URL passed to navigateTo(url, { external: true }) can break out of the content="…" attribute and inject arbitrary HTML/JavaScript that executes under the application's origin. This is a different root cause from CVE-2024-34343 (GHSA-vf6r-87q4-2vjf), which addressed javascript: protocol bypass. The issue here is triggered by any valid URL containing . Impact Applications that pass user-controlled input to navigateTo(url, { external: true }) — typically via a ?next= / ?redirect= query parameter used for post-login or "return to" flows — are vulnerable to reflected cross-site scripting. The injected script runs in the context of the application's origin during the server-rendered redirect response, before the meta-refresh fires.…
Recommended action: Upgrade to 4.4.6 or 3.21.6 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
A client-side path traversal vulnerability in Nuxt's Island payload revival mechanism allowed attackers to manipulate client-side requests to different endpoints within the same application domain when specific prerendering conditions are met. Technical Details The vulnerability occurs in the client-side payload revival process (revive-payload.client.ts) where Nuxt Islands are automatically fetched when encountering serialized nuxtisland objects. The issue affects the following flow: 1. During prerendering, if an API endpoint returns user-controlled data containing a crafted nuxtisland object 2. This data gets serialized with devalue.stringify and stored in the prerendered page 3. When a client navigates to the prerendered page, devalue.parse deserializes the payload 4. The Island reviver attempts to fetch /nuxtisland/${key}.json where key could contain path traversal sequences Prerequisites for Exploitation This vulnerability requires all of the following conditions: 1.…
Recommended action: Upgrade to 4.1.0 or 3.19.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
By sending a crafted HTTP request to a server behind an CDN, it is possible in some circumstances to poison the CDN cache and highly impacts the availability of a site. It is possible to craft a request, such as https://mysite.com/?/payload.json which will be rendered as JSON. If the CDN in front of a Nuxt site ignores the query string when determining whether to cache a route, then this JSON response could be served to future visitors to the site. Impact An attacker can perform this attack to a vulnerable site in order to make a site unavailable indefinitely. It is also possible in the case where the cache will be reset to make a small script to send a request each X seconds (=caching duration) so that the cache is permanently poisoned making the site completely unavailable. Conclusion : This is similar to a vulnerability in Next.js that resulted in CVE-2024-46982 (and see this article, in particular the "Internal URL parameter and pageProps" part, the latter being very…
Recommended action: Upgrade to 3.16.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Due to the insufficient validation of the path parameter in the NuxtTestComponentWrapper, an attacker can execute arbitrary JavaScript on the server side, which allows them to execute arbitrary commands. Details While running the test, a special component named NuxtTestComponentWrapper is available. https://github.com/nuxt/nuxt/blob/4779f5906fa4d3c784c2e2d6fe5a5c5f181faaec/packages/nuxt/src/app/components/nuxt-root.vue#L42-L43 This component loads the specified path as a component and renders it. https://github.com/nuxt/nuxt/blob/4779f5906fa4d3c784c2e2d6fe5a5c5f181faaec/packages/nuxt/src/app/components/test-component-wrapper.ts#L9-L27 There is a validation for the path parameter to check whether the path traversal is performed, but this check is not sufficient. https://github.com/nuxt/nuxt/blob/4779f5906fa4d3c784c2e2d6fe5a5c5f181faaec/packages/nuxt/src/app/components/test-component-wrapper.ts#L15-L19 Since import(...) uses query.path instead of the normalized path, a…
Recommended action: Upgrade to 3.12.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The navigateTo function attempts to blockthe javascript: protocol, but does not correctly use API's provided by unjs/ufo. This library also contains parsing discrepancies. Details The function first tests to see if the specified URL has a protocol. This uses the unjs/ufo package for URL parsing. This function works effectively, and returns true for a javascript: protocol. After this, the URL is parsed using the parseURL function. This function will refuse to parse poorly formatted URLs. Parsing javascript:alert(1) returns null/"" for all values. Next, the protocol of the URL is then checked using the isScriptProtocol function. This function simply checks the input against a list of protocols, and does not perform any parsing. The combination of refusing to parse poorly formatted URLs, and not performing additional parsing means that script checks fail as no protocol can be found. Even if a protocol was identified, whitespace is not stripped in the parseURL implementation,…
Recommended action: Upgrade to 3.12.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
he Nuxt dev server between versions 3.4.0 and 3.4.3 is vulnerable to code injection when it is exposed publicly.
Recommended action: Upgrade to 3.4.3 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.