GHSA-9v7c-q64q-vv33

Suggest an improvement
Source
https://github.com/advisories/GHSA-9v7c-q64q-vv33
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-9v7c-q64q-vv33/GHSA-9v7c-q64q-vv33.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-9v7c-q64q-vv33
Aliases
Published
2026-10-30T23:00:53Z
Modified
2026-10-30T23:15:07Z
Severity
  • 6.5 (Medium) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N CVSS Calculator
Summary
Nuxt: Dot segments in the request path bypass `server/middleware` path checks and server route rules on page routes
Details

Summary

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:

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 it fetches during server rendering.

Server-side redirect and headers route rules are skipped in the same way, so '/admin/**': { redirect: '/login' } does not redirect /%2e/admin/secret, and per-route security headers such as Content-Security-Policy are not sent.

Not affected:

  • API handlers in server/api and server/routes. Nitro's router does not resolve dot segments, so these requests do not reach the handler.
  • appMiddleware route rules and middleware declared with definePageMeta, which are matched against the resolved route.
  • Nuxt 3.x and 4.0.0 to 4.5.x, which pass the path to the page router unchanged, so these requests 404.

Browsers resolve dot segments before sending a request, so exploitation requires a client that sends the path as written.

Patches

Fixed in nuxt@4.6.3 and @nuxt/nitro-server@4.6.3. A page request whose path contains . or .. segments now receives a 404 instead of rendering the page the path resolves to, and route-rule keys and lookup paths have their dot segments resolved, including percent-encoded spellings, before they are compared.

Workarounds

Reject dot segments in a server middleware that runs before your other middleware (middleware runs in file name order):

// server/middleware/0.dot-segments.ts
export default defineEventHandler((event) => {
  if (/(?:^|\/)\.{1,2}(?:\/|$)/.test(event.path.split('?')[0])) {
    throw createError({ statusCode: 404 })
  }
})

Checking getRequestURL(event).pathname instead of event.path is not a sufficient workaround: it resolves dot segments, but keeps percent-encoding such as %61 that the page router decodes. Path checks in server middleware should also account for the page router matching paths case-insensitively unless router.options.sensitive is set.

A reverse proxy or CDN that normalises the request path before forwarding it also removes the mismatch.

Credits

Thanks to @vinzabe, @nikhilagrawalsf (Nikhil Agrawal, Mettle Labs), @0xjunwei and @kq5y, who reported this issue independently.

Database specific
{
    "cwe_ids":  [
        "CWE-41",
        "CWE-436",
        "CWE-863"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-10-30T23:00:53Z",
    "nvd_published_at":  "2026-10-29T21:17:18Z",
    "severity":  "MODERATE"
}
References

Affected packages

npm / nuxt

Package

Affected ranges

Type
SEMVER
Events
Introduced
4.6.0
Fixed
4.6.3

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-9v7c-q64q-vv33/GHSA-9v7c-q64q-vv33.json"

npm / @nuxt/nitro-server

Package

Name
@nuxt/nitro-server
View open source insights on deps.dev
Purl
pkg:npm/%40nuxt/nitro-server

Affected ranges

Type
SEMVER
Events
Introduced
4.6.0
Fixed
4.6.3

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-9v7c-q64q-vv33/GHSA-9v7c-q64q-vv33.json"