Oct 23, 2026·5 min read·2 visits
An interpretation conflict in Nuxt allows unauthenticated users to bypass route rules and appMiddleware by sending percent-encoded URLs, leading to unauthorized access to server-side rendered page content.
Nuxt versions 3.11.0 through 3.21.3 and 4.0.0 through 4.4.3 contain an interpretation conflict between the route rules matching engine and the core page routing mechanism. By submitting percent-encoded request path segments, unauthenticated attackers can bypass route rules, including appMiddleware authorization guards, and access rendered server-side page payloads.
Nuxt is an open-source web development framework built on top of Vue.js, facilitating server-side rendering (SSR), static site generation, and route-based server configurations. The framework allows developers to define routeRules in nuxt.config.ts or page metadata. These rules configure server behaviors such as appMiddleware, redirect, appLayout, ssr, and caching strategies for specific endpoint patterns.
An interpretation conflict exists between Nuxt's routeRules lookup engine and its core page router. Affected versions compare incoming requests against configured routeRules using the raw, percent-encoded URI string. Conversely, the underlying Vue page router decodes route parameters prior to executing route matching and rendering page handlers.
When an HTTP request contains percent-encoded characters in path segments, the routeRules engine fails to match the unencoded rule keys registered in the application configuration. Consequently, attached middleware—such as authentication or authorization checks—is skipped, while the page router successfully decodes the path and renders the protected resource payload.
The vulnerability stems from inconsistent URL path normalization across different architectural layers of the framework. Route rules declared in the application configuration or page metadata are indexed into a compiled matcher instance in unencoded UTF-8 format (for example, /route-rules/admin or /route-rules/测试).
When an incoming HTTP request is processed, the runtime lookup generated in #build/route-rules.mjs evaluated the raw, raw-encoded path argument (path). If an attacker sends a request using percent-encoding—such as /route-rules/%61dmin or /route-rules/%E6%B5%8B%E8%AF%95—the literal string comparison inside the lookup matcher fails to identify the entry.
Because the lookup returns an empty rule set, security controls such as appMiddleware guards are omitted. Immediately following this lookup, the Nuxt core page router processes the request, unescapes the path parameters, matches the target file-system page component, and executes server-side rendering without enforcing the intended route rules.
To resolve this issue, Nuxt implemented path normalization functions (decodeRoutePath and normalizeRouteRulePath) that decode percent-encoded sequences prior to route rule indexing and runtime matching.
The remediation introduces decodeRoutePath in packages/nuxt/src/core/utils/index.ts to decode non-reserved characters while preserving query parameters and avoiding double-decoding risks:
export function decodeRoutePath (path: string) {
if (!path.includes('%')) { return path }
const queryIndex = path.indexOf('?')
const pathname = queryIndex === -1 ? path : path.slice(0, queryIndex)
try {
return queryIndex === -1 ? decodeURI(pathname) : decodeURI(pathname) + path.slice(queryIndex)
} catch {
return path
}
}The helper normalizeRouteRulePath in packages/nuxt/src/core/utils/route-rules.ts handles case-folding and unescaping uniform keys:
export function normalizeRouteRulePath (path: string, fold: boolean): string {
const decoded = decodeRoutePath(path)
return fold ? decoded.toLowerCase() : decoded
}In addition, the server generator in packages/nitro-server/src/index.ts was updated to inject string normalization into the runtime lookup function, ensuring raw request strings are normalized before rule querying.
Exploitation requires no authentication or specialized tooling. An attacker targets an endpoint protected by a route rule configured with appMiddleware (for example, a route rule protecting /admin with an auth middleware guard).
Instead of requesting GET /admin, the attacker encodes one or more characters within the path string, submitting GET /%61dmin or GET /admi%6e. The request arrives at the server where the unpatched routeRules matcher compares /%61dmin against /admin. The matcher fails to locate a matching rule key, evaluating the rule set to empty.
The request is then passed to the page router. The router decodes /%61dmin to /admin, resolves the corresponding page component (pages/admin.vue), and executes server-side rendering. The resulting SSR HTML output and inline data payload are returned to the unauthenticated requester, bypassing the authorization check entirely.
The CVSS v3.1 score for this vulnerability is 6.5 (Medium). The primary impact is a partial loss of confidentiality and integrity due to unauthorized access to gated SSR page content and state payloads.
Because the route rule bypass affects auxiliary flags—such as redirect, appLayout, ssr, prerender, and caching behaviors—applications relying on global route rules for security enforcement or conditional page delivery are vulnerable to data leakage.
This vulnerability does not directly grant arbitrary code execution or write permissions on the underlying server filesystem. However, sensitive information rendered in SSR payloads (such as user profile data, administrative UI layouts, or internal API responses) can be accessed by unauthorized entities.
To remediate CVE-2026-114131, organizations should upgrade nuxt to version 3.21.4 (or patch release v3.21.11 / v4.5.2) for 3.x deployments, or 4.4.4 for 4.x deployments.
If immediate framework updates are not possible, reverse proxies or Web Application Firewalls (WAF) should be configured to normalize percent-encoded path sequences prior to forwarding HTTP requests to the upstream Nuxt server.
As a defense-in-depth practice, critical authorization logic should be implemented directly within individual page component guards, server middleware (server/middleware/), or API route handlers (server/api/), rather than relying solely on global routeRules configuration entries.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
nuxt nuxt | >= 3.11.0, < 3.21.4 | 3.21.4 |
nuxt nuxt | >= 4.0.0, < 4.4.4 | 4.4.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-436 / CWE-863 |
| Attack Vector | Network (Unauthenticated) |
| CVSS v3.1 Score | 6.5 (Medium) |
| EPSS Score | 0.00289 (~20th percentile) |
| Impact | Middleware Bypass / SSR Data Confidentiality Loss |
| Exploit Status | Proof-of-Concept Available |
| CISA KEV Status | Not Listed |
The software processes the same input in different contexts using different interpretations, allowing security controls to be bypassed.
A Cross-Site Scripting (XSS) vulnerability exists in Nuxt when configured with pages disabled (pages: false). ASCII C0 control characters prefixing javascript: URIs bypass internal protocol classification in the fallback router, allowing unauthenticated attackers to execute arbitrary script in the victim's origin context upon user interaction.
A Stored Cross-Site Scripting (XSS) vulnerability exists in Nuxt Server Island rendering logic when utilizing the useHeadSafe composable. Raw head attributes bypass sanitization during island serialization.
Nuxt versions prior to 4.6.2 suffer from a route rule bypass vulnerability caused by an architectural mismatch in case-sensitivity handling between the Nitro server runtime and the Vue page router. An unauthenticated remote attacker can bypass server-enforced route directives—such as redirects, security headers, and SSR controls—by altering character casing in HTTP request paths.
A heap-based buffer overflow vulnerability in Pillow PyPI binary wheels (versions 11.1.0 to 12.x) allows remote code execution or application crash via crafted JPEG 2000 files processed by the bundled libopenjp2 library.
CVE-2026-109618 (dubbed PHP2Shell) is a critical vulnerability in the PHP engine core resulting from improper out-of-memory exception handling via longjmp(). When request allocation fails mid-processing, non-local control flow bypasses cleanup procedures, leaving memory structures uninitialized or in a use-after-free state during request shutdown.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.