- A GitHub advisory says Nuxt matched route rules against the raw request path, so a percent-encoded address could skip appMiddleware on dynamic and catch-all routes.
- Security checks fail when the guard and the router read the same address differently, and the gated page can render for an unauthenticated visitor.
- Default installs from 4.4.4 and 3.21.4 are listed as unaffected, but the fix is in 4.5.2 and 3.21.11. Check pinned dependencies, or attach middleware to the page.
A guard that reads a different address than the router
Picture a security desk with a list of room names. A visitor gives the room's name in a slightly different spelling. The desk finds no match and waves the visitor through. The door opens anyway, because the building's directory understands the spelling.
That is the shape of a flaw in Nuxt, a web framework, according to an advisory in the GitHub Advisory Database published on October 22. The advisory links to the NVD entry CVE-2026-114131. The lesson is simple: a protection is only as strong as its agreement with the system it protects.
What the advisory describes
Nuxt lets teams attach rules to page addresses. One rule type, appMiddleware, runs code such as a login check before a page is served. According to the advisory, Nuxt looked up each rule using the address exactly as it arrived, with encoded characters left as typed. The router, however, decodes the address when it chooses a page.
Percent-encoding is a way to write a character as a percent sign and a code. The letter "a" can be written %61. Browsers and servers treat the two forms as the same letter.
The advisory walks through an example. A visitor requests /users/%61dmin. The router reads that as the admin user and serves the page file app/pages/users/[id].vue. The rule written for /users/admin never fires, because the encoded text is not identical to it. The login check is skipped. The server renders the gated page and hands it to an unauthenticated visitor.
An attacker needs no account and no help from a victim, the advisory says. Only plain ASCII characters are involved. The advisory does not say whether anyone has exploited the flaw.
Who is exposed, and who is not
The problem sits on dynamic routes and catch-all routes. These are pages whose address contains a variable part, such as a user ID. Purely static routes are not affected. A request for /%61dmin does not reach the page registered at /admin, and returns a 404 instead.
The bypass reaches more than login checks. Redirects, page layouts, and the settings for server rendering and prerendering are affected too. So are the caching-related flags built from cache, isr and swr, according to the advisory.
In a default install, the advisory treats 4.4.4 and 3.21.4 onward as unaffected. Those releases require a newer underlying HTTP library, which cleans up encoded paths before the router sees them. That removes the mismatch.
There is a caveat. The advisory warns that teams who pinned or overrode dependency versions below what their Nuxt release declares may still be exposed, even on a release outside the affected ranges. It adds that a single reproduction should not lead anyone to conclude they are unaffected.
The fix, and a workaround
Nuxt 4.5.2 and 3.21.11 repair the matching step. They decode both the rule keys and the incoming path first, so the two sides are compared in the same form. Case is also folded unless router.options.sensitive is set. Escapes for reserved characters, such as %2F, are left alone so decoding cannot create new path segments.
The advisory favours upgrading because it corrects Nuxt's own comparison instead of depending on a library underneath to tidy the input. There is a side benefit too. Rules for pages with non-ASCII addresses, which never matched before, work again after the upgrade.
If an upgrade is not possible, a routeRules entry should not be the only guard on a route. The advisory says to attach the middleware to the page itself. That ties the check to the route that was actually resolved, not to the raw path string.
The advisory thanks @sushi-gif, who noticed that rules written for non-ASCII paths failed to match the pages generated for them. That observation led to the review that uncovered this flaw.
How widely Nuxt appears in WebPulse's scan
In WebPulse's September 2026 scan of the Tranco top 10,000 domains, 7,064 sites responded and a platform was detected on 2,491. Nuxt was detected on 111 of them, or 4.5% of detected sites. This does not show how many are affected. That depends on version, dependency pinning, and whether a site guards dynamic routes with route rules.
Questions to put to your team
Ask which applications use Nuxt, and which version each runs. Ask whether any dependency versions are pinned or overridden below what Nuxt declares.
Ask which pages sit behind routeRules with appMiddleware, and whether any of them are dynamic or catch-all routes. Ask someone to test an encoded request against each one, and to check the result on the server-rendered response.
Ask whether sensitive pages also enforce access in the page or the data layer. A check that lives in one place can be walked around. A check that lives next to the data is harder to skip.
The takeaway is one line: protect the page that gets served, not the spelling of the address that asked for it.
Produced by the WebPulse Newsroom with AI assistance from the original reporting credited below, and checked against that source by our editorial review. How we use AI.
Original reporting: GitHub Advisory Database.





