Anatomy of the Next.js Middleware Auth Bypass CVE-2025-29927

Next.js patched a critical-severity authorization bypass in late March. The flaw, tracked as CVE-2025-29927, let attackers skip Middleware execution entirely by crafting requests with an internal header. Here's how the incident unfolded and what the team is changing as a result.

From Disclosure to Patch

The vulnerability was first reported privately on February 27 through GitHub's security channel. Because the initial report targeted Next.js 12.x, it sat lower in the triage queue. A second thread on March 1 extended the affected scope to newer versions, and internal volume delayed triage further.

The Next.js security team began investigating on March 5, and by March 14 the engineering team had confirmed the issue valid. They then worked through each deployment model:

  • Static exports were ruled out immediately since Middleware requires a server runtime.

  • Self-hosted apps running via next start or output: 'standalone' were confirmed vulnerable.

  • Vercel was incidentally safe because its routing logic runs decoupled in a separate global system.

  • Netlify and Cloudflare Workers adapters were also verified immune for the same decoupling reason.

The fix, decided that Friday, was to validate the x-middleware-subrequest header when it arrived and strip it if validation failed. A patch PR opened March 17 and merged the same day. Releases followed: 14.2.25 on March 17, 15.2.3 on March 18. GitHub issued CVE-2025-29927 on March 18, and it became public on March 21.

Two backports came after public disclosure. Next.js 13.5.9 shipped on March 22 and 12.3.5 on March 23 — both exceptions to the newly published LTS policy, made in response to community feedback.

Root Cause: An Internal Header, Externally Usable

Middleware runs before caching and routing, which makes it a convenient spot for optimistic auth checks based on cookies. The problem: Next.js uses an internal x-middleware-subrequest header to prevent recursion when Middleware re-fetches the app. Because Middleware executes in a separate process from page rendering, that header signals to the routing process that Middleware already ran. An attacker who set that header themselves could cause Middleware to be skipped entirely.

The official guidance remains unchanged: Middleware should not be the sole protection mechanism for routes. Applications that cannot upgrade immediately can filter out the header before it reaches the Next.js server as a stopgap.

Process Changes Following the Incident

Several structural changes are coming out of this postmortem.

The team acknowledged a gap in proactive communication. While Netlify and Cloudflare were verified safe before disclosure, that verification wasn't shared with them beforehand. An initial Vercel changelog also reused a template referencing the Firewall, which confused rather than clarified the situation.

Going forward, Next.js is consolidating reporting channels: both [email protected] and [email protected] are being retired in favor of GitHub's private vulnerability reporting. The team is also opening a partner mailing list at [email protected] for infrastructure providers and dependent projects.

Internally, engineers are improving how framework disclosures are triaged and how security engineers coordinate with the Next.js team. An LTS policy has been published to make version support expectations explicit. As Next.js builds an official deployment adapters API with partners like Netlify and Cloudflare, internal headers will either be documented or replaced with proper APIs. A broader security assessment of Middleware is also underway, with any findings routed through the new CVE process.

Researchers Rachid Allam and Yassir Alam received bug bounty payouts for the responsible disclosure.