Post

Exploiting CVE-2025-29927 in Next.js Middleware

Exploiting CVE-2025-29927 in Next.js Middleware

Next.js Security

Introduction

Hey Everyone! I’m Vikram Sharma, and it’s been a while since I last published a write-up. I’m back with something interesting (I know I’m super late to cover this).

We’ll be looking at CVE-2025–29927, a vulnerability that was recently disclosed in the Next.js middleware. This flaw allows attackers to bypass authentication by abusing how rewritten URLs are handled.

In this write-up, I’ll be deep-diving into the basics of middleware in Next.js, then we’ll jump into what this CVE is about and how it can be exploited. To show the real-world impact, I’ll also walk through a challenge from HackingHub based on the same CVE.

What is Next.js?

Next.js is a React framework used to build fast, full-stack web apps. It supports server-side rendering, static generation, API routes, and middleware, making it very popular among developers.

Next.js Logo

Middleware in Next.js

Middleware in Next.js allows you to run code before a request is completed. It runs on the server and lets you modify requests, redirect users, handle authentication, or rewrite URLs, all without needing a full API route.

Think of it as a gatekeeper that processes requests before they reach your pages.

What is CVE-2025-29927?

CVE-2025–29927 stems from a design flaw in how Next.js processes the x-middleware-subrequest header, which is intended to prevent infinite middleware execution loops. If an attacker includes this header with a specific value in their HTTP request, Next.js skips the middleware execution entirely, forwarding the request to its destination without applying any middleware logic, such as authentication or authorization checks.

The x-middleware-subrequest header in Next.js is used to tell the middleware when a request is coming from inside the middleware itself, like after a redirect. This helps the middleware avoid running the same code again and again, stopping it from getting stuck in a loop. It’s like a little sign that says:

“Hey, this request is from middleware, don’t run the usual checks again.”

Below is the vulnerable code that can be exploited with this method:

Vulnerable middleware.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // Vulnerability: No check on x-middleware-subrequest header
  // If user tries to access /admin, check auth token cookie
  if (request.nextUrl.pathname.startsWith('/admin')) {
    const authToken = request.cookies.get('authToken');
    if (!authToken) {
      // Redirect to login if no auth token
      return NextResponse.redirect(new URL('/login', request.url));
    }
  }
  // Allow all other requests
  return NextResponse.next();
}

In this vulnerable code:

  1. The middleware checks for an authToken cookie when a request targets a route starting with /admin. If the token is absent, it redirects the user to /login.
  2. There is no validation or filtering of the x-middleware-subrequest header, making it susceptible to manipulation.
  3. If an attacker crafts a request with the x-middleware-subrequest header set to a specific value (e.g., :middleware for modern Next.js versions), the middleware logic (including the authToken check) is bypassed entirely.
  4. This allows the attacker to access the /admin route without an authToken, as the request proceeds directly to the destination without the middleware redirecting to /login.

Affected Next.js Versions

  • Vulnerable: 11.1.4–12.3.4 → Patched in: 12.3.5
  • Vulnerable: 13.0.0–13.5.8 → Patched in: 13.5.9
  • Vulnerable: 14.0.0–14.2.24 → Patched in: 14.2.25
  • Vulnerable: 15.0.0–15.2.2 → Patched in: 15.2.3

Lab Walkthrough

In this last section, I’ll demonstrate how CVE-2025–29927 can be exploited in a real-world-like scenario using a lab from HackingHub. The goal is to bypass middleware-based authentication by exploiting the logic just as explained earlier.

This lab demonstrates how the misconfiguration can be exploited in practice and highlights the importance of proper header validation.

Flag 1:

Here’s our first web app:

HackingHub Lab Login Page

To bypass this login page:

  1. Step 1: Intercept the HTTP request using any proxy (e.g., Caido/Burp).
  2. Step 2: Add the header x-middleware-subrequest with the value middleware to the request.

Bypassing login with header injection

After bypassing the login page, I used the same header to check the event endpoint:

Accessing events endpoint

Got the first flag!

First flag captured

Flag 2:

The second target was a subdomain that had the same login page, but after checking the JavaScript, I found some interesting endpoints like /events/create.

Discovering create endpoint in JS

After trying the same approach to bypass the authentication:

Bypassing auth for the create endpoint

Got the 2nd flag!

Second flag captured

Second flag details

There can be different bypass scenarios (e.g., only getting the front-end bypass without any permissions to perform actions on the application) according to the web app you are working on. You can check Nahamsec’s video here to understand some basic scenarios.

Conclusion

In this write-up, we explored CVE-2025–29927, a critical auth bypass in Next.js middleware caused by mishandling the x-middleware-subrequest header. We broke down how middleware works, saw the vulnerable code in action, and walked through a real-world-style lab on HackingHub to exploit the flaw and grab two flags.

If you want to try this lab, check it out here.

This CVE is a reminder that even small trust assumptions—like internal headers—can lead to big security holes. Always validate what you expose, and update to the latest patched versions to stay safe.

Happy hacking and see you next time with more cool stuff! 🚀


Don’t forget to connect on Linkedin and Instagram.

This post is licensed under CC BY 4.0 by the author.