Critical Next.js Vulnerability: How a Simple Header Bypasses Authentication (CVE-2025-29927)

shadowdev
3 min read

So, NextJS disclosed an Authentication Bypass Vulnerability, with a severity of 9.1 (Critical).


TLDR

NextJS disclosed a critical authentication bypass vulnerability (CVSS 9.1).
The issue?
A specific HTTP header (x-middleware-subrequest) completely bypassed all middleware checks, allowing unauthorized access to protected routes.


What is a Middleware in NextJS?

Before we dive into the vulnerability, let's understand what middleware does in NextJS. Middleware runs before a request is completed and allows you to:

  • Rewrite paths
  • Redirect users
  • Add response headers (like CSP)
  • Perform authentication and authorization checks

Here's a simple example of middleware protecting an admin route:

typescript
1export function middleware(request: NextRequest) {
2  // Get the path
3  const path = request.nextUrl.pathname;
4  
5  // Check if user is trying to access admin area
6  if (path.startsWith('/admin')) {
7    // Get the session cookie
8    const session = request.cookies.get('session')?.value;
9    
10    // If no valid session, redirect to login
11    if (!session || !isValidSession(session)) {
12      return NextResponse.redirect(new URL('/login', request.url));
13    }
14  }
15  
16  // Continue with the request
17  return NextResponse.next();
18}

This middleware verifies whether the user has the necessary permissions to access the admin area. If the user is authorized, the request proceeds and they are redirected to the admin dashboard. If not, the user is redirected to the login page.

The Vulnerability

The vulnerability was found in NextJS internal mechanism designed to prevent infinite middleware recursion. When a request triggered middleware, NextJS would check for an internal header, x-middleware-subrequest, to decide if the middleware should execute.

If the header was present, NextJS would bypass the middleware, allowing all requests to pass through without any authorization checks.

Why this vulnerability was rated as Critical?

This vulnerability was given a critical rating (CVSS 9.1/10) for several important reasons:

  1. Authentication Bypass: This means that all authentication checks made in the Middleware would be skipped allowing the access to protected routes.
  2. Large Impact: This vulnerability was so important because NextJS is being used by critical sectors, like health-care and banking systems.
  3. Simplicity: The attack only requires adding a basic HTTP header to the requests.


Who was affected?

  • Self-hosted NextJS applications using middleware.
  • Application that rely only in the middleware for authorization and security checks.

Who was not affected?

  • Applications hosted on Vercel
  • Applications hosted on Netlify
  • Applications deployed as static exports (Middleware isn't executed)
  • Applications using Cloudflare with Managed WAF rules enabled

As of March 24, the vulnerability has been patched in the following versions:

If you can't update to a safe version, it is recommended that you prevent external user requests which contain the x-middleware-subrequest header from reaching your NextJS application.

Timeline

A timeline is a chronological record of events, showing how an issue was discovered, addressed, and resolved.

  • 2025-02-27 06:03 UTC – Vulnerability reported via GitHub.
  • 2025-03-14 17:13 UTC – NextJS team begins triage.
  • 2025-03-14 19:08 UTC – Patch released for NextJS 15.x.
  • 2025-03-14 19:26 UTC – Patch released for NextJS 14.x.
  • 2025-03-17 22:44 UTC – NextJS 14.2.25 released.
  • 2025-03-18 00:23 UTC – NextJS 15.2.3 released.
  • 2025-03-18 18:03 UTC – CVE-2025-29927 issued.
  • 2025-03-21 10:17 UTC – Security Advisory published.
  • 2025-03-22 21:21 UTC – NextJS 13.5.9 released.
  • 2025-03-23 06:44 UTC – NextJS 12.3.5 released.

References

If you want to dive deeper into this vulnerability, check the more in-depth articles.

Liked this article? Feel free to buy me a coffee!

Buy me a coffee
Made with ❤️ byshadow