Back to Blog
high SEVERITY8 min read

How Middleware and Proxy Bypass happens in Next.js App Router and how to fix it

CVE-2026-64642 is a high-severity authentication bypass vulnerability in Next.js that affects App Router applications using Turbopack with a single locale configuration. The flaw allows attackers to circumvent middleware and proxy security controls, potentially gaining unauthorized access to protected routes. Upgrading from Next.js 16.2.7 to 16.2.11 closes the vulnerability entirely.

O
By Orbis AppSec
Published August 26, 2026Reviewed August 26, 2026

Answer Summary

CVE-2026-64642 is a high-severity middleware and proxy bypass vulnerability (CWE-287) in Next.js versions prior to 16.2.11, affecting App Router applications that use Turbopack and a single locale. Attackers can craft requests that skip middleware execution entirely, bypassing authentication and authorization checks enforced at the middleware layer. The fix is a dependency upgrade from `next@16.2.7` to `next@16.2.11` in `package-lock.json`, which patches the internal routing logic responsible for the bypass.

Vulnerability at a Glance

cweCWE-287
fixUpgrade next from 16.2.7 to 16.2.11 in package-lock.json
riskUnauthenticated access to routes protected by Next.js middleware
languageJavaScript / TypeScript
root causeTurbopack's single-locale routing path skips middleware execution in the App Router
vulnerabilityMiddleware / Proxy Authentication Bypass

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:

  1. The project uses the App Router (the app/ directory introduced in Next.js 13+)
  2. Turbopack is enabled (via next dev --turbo or the turbopack config key)
  3. The i18n configuration 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 defaultLocale to next.config.js for 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 /dashboard route group containing sensitive user data
  • A middleware.ts that checks for a valid session cookie and redirects to /login if absent
  • Turbopack enabled in next.config.js
  • i18n: { locales: ['en'], defaultLocale: 'en' } in next.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 version field (16.2.716.2.11)
  • A new resolved URL pointing to the patched tarball
  • A new integrity hash 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

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.json integrity hashes are a security control: the updated SHA-512 hashes for @next/env-16.2.11 and @next/swc-*-16.2.11 ensure 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.json is a low-cost, high-value control that caught a high-severity auth bypass at the PR stage.
  • The ^ semver range in package.json was insufficient protection: ^16.2.6 allowed 16.2.7 (vulnerable) to be installed. Explicitly bumping the lower bound to ^16.2.11 closes the window for future installs.

How Orbis AppSec Detected This

  • Source: The package-lock.json dependency manifest, which records the exact resolved version of next (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 next from 16.2.7 to 16.2.11 in both package.json and package-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.


References

Frequently Asked Questions

What is a middleware bypass vulnerability in Next.js?

A middleware bypass means an attacker can craft a request that skips the middleware function entirely, so any authentication, authorization, or rate-limiting logic placed there never runs.

How do you prevent middleware bypass in Next.js?

Keep Next.js up to date, avoid relying solely on middleware for security-critical checks, and apply defense-in-depth by also validating sessions inside route handlers and API endpoints.

What CWE is middleware bypass?

CWE-287 (Improper Authentication) — the security control that should verify identity is circumvented before it can execute.

Is upgrading the package enough to prevent this vulnerability?

Yes for CVE-2026-64642 specifically, but as a general principle you should also add server-side session validation inside protected routes so a future bypass cannot expose sensitive data.

Can static analysis detect middleware bypass vulnerabilities?

Scanners like Trivy can flag known-vulnerable package versions. Dynamic analysis and manual code review are also important for detecting logic-level bypass patterns.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #388

Related Articles

critical

How Missing Authentication Middleware Happens in Node.js APIs and How to Fix It

A critical vulnerability in a Node.js Panel Connector API (CVE-2025-7783) left 14 endpoints—including shell command execution, file deletion, and file writing—completely open to unauthenticated access. The comment in the source code even declared "NO AUTH — Full Open Access," making it a textbook example of a missing authentication control. The fix adds a Bearer token middleware guard on all `/api` routes, blocking unauthorized requests before they reach any sensitive handler.

critical

How OAuth CSRF Attacks Happen in Node.js and How to Fix Them

A missing OAuth state parameter validation in `src/account_manager.js` left the `startOAuthServer()` function vulnerable to CSRF attacks, allowing an attacker to inject their own authorization code into a victim's active OAuth session. The fix generates a cryptographically random state token using `crypto.randomBytes()`, returns it alongside the server handle, and rejects any callback where the returned state doesn't match — closing the attack window entirely. This affects all downstream consume

critical

How Unauthenticated API Endpoint Exposure happens in Node.js and how to fix it

A critical vulnerability in `api/firebase-config.js` exposed all Firebase configuration values — including API keys, app IDs, and project IDs — to any unauthenticated caller. With no access controls, CORS restrictions, or rate limiting in place, attackers could retrieve live credentials and directly access Firebase services. The fix adds shared-secret authentication using timing-safe comparison, origin validation, and method enforcement.

critical

How OAuth 2.0 CSRF happens in PHP and how to fix it

A critical OAuth 2.0 CSRF vulnerability in `login_weibo.php` allowed attackers to forge Weibo login requests by exploiting the missing `state` parameter validation. Without this check, an attacker could trick a victim's browser into completing an OAuth flow with the attacker's authorization code, potentially hijacking the victim's session. The fix generates a cryptographically random state token, stores it in the session, and validates it on callback.

critical

How Unauthenticated API Endpoints happen in Node.js Express and how to fix it

The `/token` endpoint in `plugin/multiplex/index.js` generated presentation control tokens without verifying the requester's identity, allowing any attacker with network access to seize control of a live reveal.js presentation. The fix restricts token generation to localhost-only requests and replaces a broken cryptographic primitive with a proper SHA-256 hash. Together, these changes eliminate both the access-control gap and a secondary cryptographic weakness in a single targeted patch.

high

How Dependabot Missing Cooldown happens in GitHub Actions and how to fix it

A high-severity misconfiguration in `.github/dependabot.yml` left this Node.js library without a cooldown period on dependency updates, meaning Dependabot could immediately propose upgrades to newly published — potentially malicious or unstable — package versions. The fix adds a `cooldown` block with `default-days: 7` to both the `npm` and `github-actions` ecosystems, introducing a mandatory waiting period before any newly released version is surfaced as an update candidate. Because this project