Critical Next.js Middleware Vulnerability (CVE-2025-29927) - Why Updating Your Dependencies Isn't Optional
On 21 March 2025, a critical vulnerability was publicly disclosed in Next.js - one of the most widely used React frameworks in the world. Tracked as CVE-2025-29927 and carrying a CVSS score of 9.1 out of 10, this flaw allows attackers to completely bypass middleware-based authorisation checks with nothing more than a single crafted HTTP header.
As a team that builds and maintains applications with Next.js, this one hit close to home. It is a stark reminder of why keeping your dependencies up to date is not just good practice - it is a fundamental security requirement.
What Happened
Security researchers Rachid Allam (zhero) and Yasser Allam (inzo_) discovered that Next.js had a critical flaw in how it handled an internal HTTP header called x-middleware-subrequest. This header was designed to prevent infinite loops when middleware triggers internal sub-requests. The problem was that Next.js trusted this header from external requests without proper validation.
By including this header in a request with the correct value - which was predictable based on the middleware file path - an attacker could trick the framework into believing the request was an internal sub-request. Next.js would then skip middleware execution entirely, meaning any security checks implemented in middleware, such as authentication and authorisation, were completely bypassed.
In practical terms, a simple GET request to a protected admin route with the right header value was all it took to gain unauthorised access. No credentials needed. No sophisticated exploit chain. Just one header.
Which Versions Were Affected
The scope of this vulnerability was enormous. It affected every version of Next.js from 11.1.4 onwards, spanning years of releases across the 11.x, 12.x, 13.x, 14.x and 15.x branches. The patched versions are:
- 15.2.3 for the 15.x branch
- 14.2.25 for the 14.x branch
- 13.5.9 for the 13.x branch
- 12.3.5 for the 12.x branch
If you are running any version below these, your self-hosted Next.js application may be vulnerable. It is worth noting that applications hosted on Vercel were not affected due to how their platform decouples the routing logic, and static exports were also safe since middleware requires a server runtime to function.
How the Exploit Worked
The technical details varied slightly depending on the Next.js version, but the core issue was consistent. In older versions (pre-12.2), middleware files were located at pages/_middleware, and including that path as the value of the x-middleware-subrequest header was enough to bypass it.
From version 12.2 onwards, middleware moved to the project root as middleware.ts (or within a /src directory), simplifying the possible header values to middleware or src/middleware.
In the latest 15.x versions, Next.js had introduced a recursion depth check to prevent infinite loops. The framework would check how many times the middleware had been called by examining the header value. An attacker could bypass this by repeating the middleware path enough times to hit the MAX_RECURSION_DEPTH limit (set to 5), causing the framework to skip middleware execution entirely. The crafted header looked something like: middleware:middleware:middleware:middleware:middleware.
A proof of concept was publicly released just two days after disclosure, on 23 March 2025, making rapid patching absolutely critical.
Why This Matters Beyond Next.js
This vulnerability is a textbook example of why layered security - sometimes called defence in depth - is so important. Many developers rely on middleware as their primary line of defence for authentication and authorisation. When that single layer fails, there is nothing else standing between an attacker and your protected resources.
We see this pattern regularly. Middleware is convenient. It runs before your route handlers, it is easy to configure, and it feels like a natural place to put auth checks. But convenience should never be confused with robustness.
The lesson here is clear: middleware should be one layer of your security architecture, not the only one. You should always implement authorisation checks at the route or controller level as well. If you are building APIs - as we often do - you should be validating permissions at the service layer, not just at the edge.
The Disclosure Timeline - A Cautionary Note
The disclosure timeline for this vulnerability also highlights some important points about how we handle security reports as an industry. The researchers reported the vulnerability to Vercel on 27 February 2025. The initial response on 5 March suggested that 12.x was no longer supported, apparently before the team had fully reviewed the report indicating all versions were affected. It was not until 17 March that Vercel confirmed the full scope, and patches were released on 18 March.
The CVE was made public on 21 March, and a proof of concept followed on 23 March. That is a tight window between public disclosure and weaponisation, and it underscores why organisations need processes in place to respond to security advisories quickly.
What You Should Do Right Now
If you are running a self-hosted Next.js application, here is what we recommend:
- Update immediately. Upgrade to the patched version for your branch (15.2.3, 14.2.25, 13.5.9 or 12.3.5). This should be your top priority.
- If you cannot update straight away, configure your reverse proxy (Nginx, Apache, Cloudflare or similar) to strip the
x-middleware-subrequestheader from all incoming external requests. - Review your security architecture. Audit where you rely on middleware alone for access control. Add redundant authorisation checks at the route handler and service layer.
- Check your access logs. Look for any requests containing the
x-middleware-subrequestheader from external IP addresses, which could indicate attempted or successful exploitation. - Establish a patching cadence. If you do not already have a process for monitoring and applying security updates to your dependencies, now is the time to build one.
Our Wider Take on Dependency Updates
We work with a range of frameworks and technologies - from Laravel on the backend to Next.js and React on the frontend, alongside CMS platforms like Craft CMS. Across all of these, one thing remains constant: keeping your software up to date is not optional.
It is easy to fall into the trap of thinking "if it works, do not touch it." But every unpatched dependency is a potential attack vector. CVE-2025-29927 is a perfect example. The vulnerability had been present in the Next.js codebase for years, quietly waiting to be discovered. The only thing separating a secure application from a compromised one was whether the team had applied the update.
Security updates are not disruptive overhead. They are an essential part of maintaining any production application. Treat them with the same urgency you would give to a production outage, because in many cases, that is exactly what an exploited vulnerability becomes.
Final Thoughts
CVE-2025-29927 was a wake-up call for the Next.js community, but its lessons apply far beyond a single framework. Build with layers. Update with urgency. And never assume that a single security check is enough to protect your users and their data.
If you are unsure whether your applications are affected or want help reviewing your security posture, get in touch with us. We are always happy to help.
