The Vulnerability at a Glance
| Field | Detail |
|---|---|
| CVE | CVE-2026-64642 |
| Severity | High |
| Affected package | next < 16.2.11 |
| Root cause | Middleware skipped in Turbopack + single-locale App Router path |
| Fix | Upgrade next to 16.2.11 |
| CWE | CWE-287 — Improper Authentication |
Introduction
The package-lock.json in this project pinned next at ^16.2.6, which resolved to 16.2.7 at install time. That version contains a critical flaw in how the Turbopack dev/build pipeline handles routing when exactly one locale is configured in the Next.js App Router. Under those conditions, the internal routing code takes a code path that silently skips middleware execution — meaning every middleware.ts or middleware.js file in the project becomes a dead letter for the affected requests.
For any application that gates protected pages behind middleware-level authentication (a very common Next.js pattern), this is a direct authentication bypass: an attacker who knows the right request shape can walk straight past the auth check and land on a route they were never meant to reach.
The Vulnerability Explained
What Next.js Middleware Is Supposed to Do
Next.js middleware runs before a request reaches a page, layout, or API route. Developers use it to:
- Redirect unauthenticated users to
/login - Enforce role-based access control across a route group
- Apply geo-blocking or rate limiting uniformly
- Rewrite or proxy requests to backend services
A typical middleware.ts looks like this:
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('session')?.value;
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*', '/admin/:path*'],
};
The security model assumes this function always runs for matched paths. CVE-2026-64642 breaks that assumption.
The Specific Trigger Conditions
The bypass activates when all three of the following are true:
- The project uses the App Router (the
app/directory introduced in Next.js 13+) - Turbopack is enabled (via
next dev --turboor theturbopackconfig key) - The
i18nconfiguration specifies exactly one locale
When these conditions align, Turbopack's internal route resolver takes a fast-path branch that omits the middleware invocation step. The result is that requests matching the middleware matcher pattern bypass the function entirely and are served directly.
Why This Specific Configuration Is Common
Single-locale Turbopack setups are not edge cases. Many teams:
- Enable Turbopack for faster local development and CI builds
- Add a single
defaultLocaletonext.config.jsfor future i18n readiness without actually serving multiple languages yet - Rely heavily on middleware for JWT or session-cookie authentication
This combination is entirely reasonable and well-documented in the Next.js guides, which makes the silent bypass especially dangerous — developers would have no reason to suspect their middleware wasn't running.
The Vulnerable Package Version
The package-lock.json before the fix contained:
"node_modules/@next/env": {
"version": "16.2.7",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.7.tgz",
"integrity": "sha512-tMJizPlj6ZYpBMMdK8S0LJufrP4QTdR6pcv9KQ/bVETPAmg0j1mlHE9G2c38UyGHxoBapgwuj7XjbGJ2RcDFOg=="
}
And the top-level dependency was pinned to:
"next": "^16.2.6"
Because ^16.2.6 allows any 16.2.x release, npm install resolved this to 16.2.7 — the vulnerable version.
Attack Scenario
Consider a Next.js application with:
- A
/dashboardroute group containing sensitive user data - A
middleware.tsthat checks for a validsessioncookie and redirects to/loginif absent - Turbopack enabled in
next.config.js i18n: { locales: ['en'], defaultLocale: 'en' }innext.config.js
An attacker who knows (or guesses) the application's framework and configuration can send a direct GET /dashboard request without any session cookie. On a non-vulnerable Next.js version, the middleware intercepts this and returns a 302 redirect to /login. On 16.2.7 with Turbopack and a single locale, the middleware function never fires — the request reaches the app/dashboard/page.tsx render function directly and the page is served in full.
No credentials. No tokens. No exploit code. Just a plain HTTP request.
The Fix
What Changed in package-lock.json
The fix is a targeted dependency upgrade. The diff shows two categories of change:
1. Top-level version constraint updated:
- "next": "^16.2.6",
+ "next": "^16.2.11",
This ensures future npm install runs cannot accidentally resolve back to a vulnerable 16.2.x version below 16.2.11.
2. Resolved package versions and integrity hashes updated:
"node_modules/@next/env": {
- "version": "16.2.7",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.7.tgz",
- "integrity": "sha512-tMJizPlj6ZYpBMMdK8S0LJufrP4QTdR6pcv9KQ/bVETPAmg0j1mlHE9G2c38UyGHxoBapgwuj7XjbGJ2RcDFOg=="
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.11.tgz",
+ "integrity": "sha512-0do5A3BJ2gxWr0ZCMcD6BhW+e595jyxdTl3rXTS6lOtD8ektMiW6CO+EPwt1Eca1DBnm90r/7GdiKWBKxH++DA==",
+ "license": "MIT"
},
The same pattern repeats for platform-specific SWC compiler packages (@next/swc-darwin-arm64, @next/swc-darwin-x64, and their Linux/Windows equivalents). Each receives:
- An updated
versionfield (16.2.7→16.2.11) - A new
resolvedURL pointing to the patched tarball - A new
integrityhash that cryptographically verifies the correct artifact is downloaded - An explicit
"license": "MIT"field (a minor metadata improvement in the new release)
Why Updating the Lock File Matters
It is not enough to change only package.json. The package-lock.json contains the exact resolved versions and integrity hashes that npm ci uses in CI/CD pipelines. If only package.json were updated, a npm ci run would fail or — worse — silently install a cached version of 16.2.7 from a local npm cache. Updating both files ensures every environment (developer laptops, CI runners, production build servers) installs 16.2.11.
What Next.js 16.2.11 Actually Fixes
The patch in 16.2.11 corrects the Turbopack route resolution logic so that the middleware invocation step is never skipped, regardless of locale count. The single-locale fast path now correctly passes requests through the middleware pipeline before handing them off to the App Router renderer.
Prevention & Best Practices
1. Pin Dependencies Precisely in Lock Files
Use npm ci (not npm install) in CI/CD pipelines. This command respects the lock file exactly and refuses to install if package.json and package-lock.json are out of sync — preventing silent version drift.
2. Run SCA Scanners as Part of CI
Tools like Trivy, Snyk, and Socket scan your package-lock.json against CVE databases on every pull request. This is exactly how CVE-2026-64642 was detected here — Trivy flagged the vulnerable next@16.2.7 entry before it reached production.
# Example GitHub Actions step
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'HIGH,CRITICAL'
3. Do Not Rely Solely on Middleware for Security
The Next.js documentation itself notes that middleware runs in the Edge Runtime and should be treated as a first line of defense, not the only one. For truly sensitive routes, validate the session inside the route handler or server component as well:
// app/dashboard/page.tsx
import { getServerSession } from 'next-auth';
import { redirect } from 'next/navigation';
export default async function DashboardPage() {
const session = await getServerSession();
if (!session) {
redirect('/login'); // defense-in-depth
}
// render protected content
}
This defense-in-depth approach means a future middleware bypass — in any framework version — cannot expose sensitive data on its own.
4. Subscribe to Security Advisories
- Watch the Next.js GitHub repository for security advisories
- Enable Dependabot or Renovate to automatically open PRs when new patch versions are released
- Subscribe to the npm security advisories feed for your critical dependencies
5. Relevant Standards
- OWASP Top 10 A07:2021 — Identification and Authentication Failures: Middleware bypass is a textbook example of this category
- CWE-287 — Improper Authentication: The security control (middleware) is present but can be circumvented
- OWASP ASVS v4.0 Section 4.1: Requires that access control checks are enforced server-side and cannot be bypassed by client manipulation
Key Takeaways
- Single-locale Turbopack setups are not safe from middleware bypass on
next@16.2.7— this is a specific, reproducible trigger condition, not a theoretical edge case. package-lock.jsonintegrity hashes are a security control: the updated SHA-512 hashes for@next/env-16.2.11and@next/swc-*-16.2.11ensure the correct, patched tarballs are installed everywhere.- Middleware-only auth is fragile: CVE-2026-64642 demonstrates why server component and API route handlers should independently verify sessions, even when middleware is in place.
- Trivy caught this before deployment: static dependency scanning on
package-lock.jsonis a low-cost, high-value control that caught a high-severity auth bypass at the PR stage. - The
^semver range inpackage.jsonwas insufficient protection:^16.2.6allowed16.2.7(vulnerable) to be installed. Explicitly bumping the lower bound to^16.2.11closes the window for future installs.
How Orbis AppSec Detected This
- Source: The
package-lock.jsondependency manifest, which records the exact resolved version ofnext(16.2.7) used across all environments. - Sink: The Turbopack route resolver's middleware invocation logic within
next@16.2.7, which omits the middleware execution step for App Router requests when a single locale is configured — effectively a no-op security control for matched routes. - Missing control: The internal routing pipeline lacked a guard ensuring middleware was always invoked before route rendering, regardless of locale count or build tool selection.
- CWE: CWE-287 — Improper Authentication (the authentication middleware is present but bypassable due to a routing logic defect).
- Fix: Updated
nextfrom16.2.7to16.2.11in bothpackage.jsonandpackage-lock.json, replacing all affected@next/*package entries and their integrity hashes with the patched versions.
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
CVE-2026-64642 is a sharp reminder that framework internals — particularly the interaction between build tools, routing engines, and middleware pipelines — can create authentication bypasses that are completely invisible in application code. The middleware.ts file looked correct. The next.config.js looked correct. The vulnerability lived entirely inside the next package itself, triggered by a specific combination of features that many real-world projects use.
The fix is straightforward: upgrade to next@16.2.11. But the broader lesson is architectural — authentication logic should never live in a single layer. Combine middleware-level checks with server-side session validation inside route handlers, keep your dependency scanner running on every PR, and treat your package-lock.json as a security artifact that deserves the same attention as your source code.