Oct 23, 2026·6 min read·4 visits
A case-sensitivity mismatch between Nitro server route rules and the Nuxt Vue page router allows attackers to bypass security headers, redirects, and proxy rules by requesting paths with altered casing (e.g., `/Admin/secret` instead of `/admin/secret`).
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.
Nuxt is an open-source web development framework built on Vue.js that utilizes Nitro as its underlying server engine. In Nuxt applications, administrators define server-side operational behaviors using the routeRules configuration object within nuxt.config.ts. These rules govern server-level features including HTTP redirects, security header injections, proxy forwarding, rendering mode toggles (ssr: false), and script execution restrictions (noScripts).
The framework exposes an operational mismatch between client-side routing resolution and server-side request evaluation. By default, Nuxt configures client-side page routing with case-insensitive path matching (router.options.sensitive: false). Under this configuration, an incoming request for /Admin/secret resolves to the same Vue page component as /admin/secret.
Prior to version 4.6.2, Nitro evaluated server-side routeRules strictly against the raw case-sensitive path string provided in the HTTP request line. When an HTTP request contained character casing that differed from the rule definitions in nuxt.config.ts, Nitro failed to match the defined route rule and returned an empty directive set. Consequently, the request bypassed server-side protections while successfully rendering the underlying page component.
The fundamental flaw lies in inconsistent path normalization across the architectural boundary separating Nitro's server router and Nuxt's page router. Classified under CWE-178 (Improper Handling of Case Sensitivity) and CWE-863 (Incorrect Authorization), the vulnerability occurs because Nitro's internal router matched request paths literally without applying case-folding transformations when router.options.sensitive was disabled.
Consider a scenario where an application configures a security restriction or redirect rule in nuxt.config.ts:
export default defineNuxtConfig({
routeRules: {
'/admin/**': { redirect: { to: '/login', statusCode: 307 } },
'/docs': { headers: { 'x-docs-security': '1' } },
'/app/spa': { ssr: false }
}
})When a client issues an HTTP request for GET /Admin/dashboard, Nitro's request handler invokes getRouteRules(event). The matcher evaluates /Admin/dashboard against the stored key /admin/**. Because of the exact-match requirement in the radix tree comparison, the lookup fails to identify the rule and returns {}.
Following rule evaluation, the execution pipeline hands off request processing to the Vue page renderer. The client-side page router evaluates /Admin/dashboard, normalizes the route path case-insensitively, and renders app/pages/admin/dashboard.vue. The client receives the response without the enforcement of the intended redirect or security headers.
Security fix f6cfee52cf9576ddc4f4ee83b486969328b358f8 by Daniel Roe addresses the discrepancy by introducing unified case normalization in Nitro's server runtime.
The fix introduces a dedicated server plugin (packages/nitro-server/src/runtime/plugins/route-rules.ts) and a normalized matching utility (packages/nitro-server/src/runtime/utils/route-rules.ts). The new implementation case-folds both configured keys and runtime HTTP path strings unless router.options.sensitive is explicitly enabled.
import { defu } from 'defu'
import type { H3Event } from 'h3'
import { useRuntimeConfig } from 'nitropack/runtime'
import type { NitroRouteRules } from 'nitropack/types'
import { createRouter, toRouteMatcher } from 'radix3'
import type { RouteMatcher } from 'radix3'
import { withoutBase } from 'ufo'
import { normalizeRouteRulePath } from '#internal/nuxt/route-rules.mjs'
let matcher: RouteMatcher | undefined
function getMatcher (): RouteMatcher {
if (!matcher) {
const routes: Record<string, NitroRouteRules> = {}
// Normalize each configured route key according to router sensitivity options
for (const [route, rules] of Object.entries(useRuntimeConfig().nitro?.routeRules || {})) {
routes[normalizeRouteRulePath(route)] = rules as NitroRouteRules
}
matcher = toRouteMatcher(createRouter({ routes }))
}
return matcher
}
export function matchRouteRules (path: string): NitroRouteRules {
// Normalize incoming request path prior to radix tree lookup
return defu({}, ...getMatcher().matchAll(normalizeRouteRulePath(path)).reverse()) as NitroRouteRules
}The fix ensures that normalizeRouteRulePath converts all route rule paths and incoming URL targets to lowercase when case-sensitivity is turned off, ensuring parity between server processing and page rendering.
Exploiting CVE-2026-114132 requires no authentication or specialized payload construction. An attacker only needs network access to an affected Nuxt server where security-relevant logic is delegated to routeRules.
Consider an deployment where administrative pages reside under /admin/**, protected by a redirect rule pointing unauthenticated traffic to /login:
# Standard request: Redirect rule triggers as intended
curl -i http://target-app.local/admin/dashboard
HTTP/1.1 307 Temporary Redirect
Location: /login
# Exploitation request: Bypasses server redirect rule, renders page
curl -i http://target-app.local/Admin/dashboard
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
<!-- Rendered administrative dashboard page content -->The operational consequences vary based on the specific directive bypassed:
routeRules.Content-Security-Policy, X-Frame-Options, or custom authorization headers defined under specific path prefixes.ssr: false), causing unexpected server CPU load or memory usage.The technical impact of CVE-2026-114132 is categorized as moderate integrity and confidentiality loss (CVSS v4.0 Score: 6.3). The CVSS vector is CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N.
The vulnerability does not grant arbitrary code execution or direct file system access. Instead, it degrades security controls that rely exclusively on server-side path rules. If application security relies on routeRules for access control or header-based security policies, those policies can be silently subverted.
> [!NOTE]
> Access control checks implemented within custom middleware (server/middleware/), page middleware (defineNuxtRouteMiddleware), or component data fetching methods (useAsyncData / useFetch) process paths independently and are not vulnerable to this bypass.
The primary remediation for CVE-2026-114132 is updating the nuxt dependency to version 4.6.2 or higher in the project root.
# Upgrade via pnpm
pnpm update nuxt@^4.6.2
# Upgrade via npm
npm install nuxt@^4.6.2
# Upgrade via yarn
yarn add nuxt@^4.6.2If immediate dependency upgrades are not possible, administrators can apply a temporary workaround in nuxt.config.ts by explicitly enabling case-sensitive routing:
// nuxt.config.ts
export default defineNuxtConfig({
router: {
options: {
sensitive: true
}
}
})> [!IMPORTANT]
> Configuring sensitive: true inside app/router.options.ts is insufficient to patch this vulnerability. The Nitro server engine reads the configuration directly from nuxt.config.ts during build time.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
nuxt nuxt | >= 4.1.3, < 4.6.2 | 4.6.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-178 / CWE-863 |
| CVSS v4.0 Vector | CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N |
| CVSS Score | 6.3 (Medium) |
| EPSS Score | 0.00314 (23.05th percentile) |
| Attack Vector | Network (Unauthenticated HTTP) |
| Exploit Status | Proof of Concept in Fix Commit |
| CISA KEV Status | Not Listed |
The software does not correctly handle case sensitivity when processing user input, leading to unexpected behavior or security rule bypasses.
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.
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.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.