Skip to content

Next.js CVE-2025-29927 Reproduction Notes

Next.js CVE-2025-29927 in Vulhub: how x-middleware-subrequest affects middleware authorization, with an initial analysis of the mechanism.

1/15/2024

#CTF#Web Security#Security Research#Next.js

A Brief Introduction to Next.js

I see many blogs and other sites using Next.js.

Next.js is an open-source frontend development framework based on React, used to build modern web applications, especially applications using server-side rendering (SSR) and static site generation (SSG). It is developed and maintained by Vercel (formerly Zeit).

Next.js backend services can indeed run in two modes: Node.js Runtime and Edge Runtime.

Edge computing

Here, let’s take a closer look at Edge Functions (edge functions / edge computing).

An Edge Function is a small function that runs on a server closer to the user. It responds quickly with low latency and is suited to providing the “first response” to a request.

Edge computing is a distributed-computing paradigm. It pushes computation and data storage closer to where they are needed — the source of data generation or the end user. This contrasts with traditional centralized cloud computing, where all data is sent to a distant, large data center for processing.

PlatformProduct name
VercelEdge Functions
CloudflareWorkers
NetlifyEdge Functions
AWSLambda@Edge
DenoDeno Deploy
BunBun Edge Runtime (experimental)

Vulnerability reproduction

Reproducing the environment

Versions earlier than Next.js 14.2.25 and 15.2.3 are affected.

I reproduced it here using a Vulhub environment.

vulhub/next.js/CVE-2025-29927 at master · vulhub/vulhub

The environment opens to a login page.

If we log in with the default administrator username and password,

we can see that we enter the administration panel.

We analyze it in Yakit.

We add the following to the request:

x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware

The result shows that we bypassed authorization and authentication.

Vulnerability principles

How Next.js handles a special internal HTTP header, x-middleware-subrequest.

Purpose of the **x-middleware-subrequest** header: This header is intended for internal use by the Next.js framework, mainly to prevent middleware from entering an infinite recursive loop while handling requests. When middleware internally triggers a request to another URL that might also require the same middleware, this header tracks the call level or state.

Therefore, our bypass mechanism works as follows:

When a Next.js application receives a request with a carefully crafted **x-middleware-subrequest** header, the framework incorrectly determines that the request appears to have already been processed by the middleware (or has reached the maximum recursion depth), and decides to skip the middleware logic that should have run.

As a result, we can access resources that should be protected.


Returning to the payload, I have seen some sources say:

In some versions, Next.js checks the value of the _x-middleware-subrequest_ header to prevent infinite recursion. It counts the number of times the header value contains the current middleware name. The default maximum recursion depth (_MAX_RECURSION_DEPTH_) is 5.

curl -i -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" http://127.0.0.1:3000

So when Next.js receives this request,

it assumes there is no need to execute the middleware again, skips its processing logic, and passes the request to the next stage.

Vulnerability detection

See THM for details.

TryHackMe | Cyber Security Training

Next post

Java Two Sum Practice

SEARCH / QUICK FIND

Search English content

Try searching