How to Fix the Next.js x-middleware-subrequest Vulnerability

Table of Contents
Summery
  • CVE-2025-29927 (CVSS 9.1) allows attackers to bypass Next.js middleware by injecting the x-middleware-subrequest header, granting unauthorized access to protected pages.
  • The flaw affects almost all self-hosted versions of Next.js from v11 up to recent v15 releases; Vercel-hosted apps are already patched

Langit Eastern

A severe security oversight has been uncovered in Next.js, one of the world's most popular React frameworks. Assigned a critical CVSS score of 9.1, CVE-2025-29927 allows attackers to completely bypass authentication and authorization checks implemented in Next.js Middleware.

 

The vulnerability affects self-hosted applications ranging from version 11.x through nearly all recent 14.x and 15.x releases. While deployments hosted directly on Vercel were automatically patched, thousands of self-hosted enterprise applications remain exposed to a trivial exploit vector involving a single HTTP header.

 

The Anatomy of the Bypass

Middleware in Next.js is designed to intercept requests before they reach the page or API route. It is the standard method for enforcing authentication, managing redirects, and applying security headers like Content Security Policy (CSP).

The vulnerability stems from a logical flaw in how Next.js handles internal recursion. To prevent middleware from triggering infinite loops—where a request calls middleware, which calls itself endlessly—the framework utilizes a specific HTTP header: x-middleware-subrequest.

 

When Next.js sees this header with a specific value, it assumes the middleware has already run and explicitly skips execution to prevent a loop. The critical failure was trusting this header from user input. An attacker simply needs to inject this header into their request to tell the server, "I've already been checked," effectively walking past the security guard without showing ID.

 

Technical Note: The specific value required to trigger the bypass varies by version. Older versions (pre-12.2) looked for file paths like pages/_middleware, while modern versions check for a recursion depth string like middleware:middleware:middleware:middleware:middleware.

 

Beyond Basic Exploitation: The Assetnote Discovery

Initial reports and public scanning templates focused on detecting this vulnerability by looking for rewrite headers. However, security researchers at Assetnote discovered these checks were insufficient for many real-world deployments.

Most authentication middleware performs a redirect (e.g., sending a user to /login) rather than a rewrite. Public scanners looking for x-middleware-rewrite headers were missing vulnerable targets because redirects often "swallow" these internal headers.

 

Assetnote’s research revealed that by appending x-nextjs-data: 1 to the request, researchers could force the server to leak internal headers even during a redirect, confirming the vulnerability where others missed it. Furthermore, they developed a "polyglot" payload—a single complex header string designed to trigger the bypass across multiple Next.js versions simultaneously.

 

The Ripple Effect: It's Not Just Authentication

While the primary risk is unauthorized access to protected routes (like /admin dashboards), the implications extend further.

  • CSP Bypass: If your application relies on middleware to inject Content Security Policy headers, this bypass prevents those headers from being applied, opening the door to Cross-Site Scripting (XSS).
  • Cache Poisoning: Attackers can leverage this bypass to cache 404s or 500 errors, potentially taking down the application for legitimate users (Denial of Service).

 

Immediate Remediation and Defense

If you are self-hosting Next.js, you must assume your application is vulnerable if you fall within the affected version ranges.

 

1. The Primary Fix: Patching Update your Next.js dependency immediately to the patched versions:

  • v15.x: Update to 15.2.3 or later.
  • v14.x: Update to 14.2.25 or later.
  • v13.x: Update to 13.5.9 or later.
  • v12.x: Update to 12.3.5 or later.

 

2. The Emergency Workaround: Header Stripping If you cannot upgrade immediately, you must block the x-middleware-subrequest header at your network edge.

  • Nginx: Add proxy_set_header x-middleware-subrequest ""; to your configuration.
  • Apache: Use RequestHeader unset x-middleware-subrequest.
  • Express/Node Custom Server: Implement a simple middleware at the top of your stack to delete this header from incoming requests.

 

This vulnerability serves as a stark reminder that internal state mechanisms should never rely on client-controlled input. The architecture effectively trusted the client to report its own validation status—a classic "security through obscurity" failure that has now been laid bare.