セキュリティブログ

Another (A Bit Earlier) Next.js Middleware Bypass Vulnerability: CVE-2024-51479

Another (A Bit Earlier) Next.js Middleware Bypass Vulnerability: CVE-2024-51479

更新日:2025.03.27

I'm Yamazaki, a Security Engineer at GMO Cybersecurity by Ierae, Inc.

Recently, a vulnerability that bypasses Next.js middleware has been disclosed as CVE-2025-29927, and it has been the topic of much discussion.

Next.js and the corrupt middleware: the authorizing artifact

This vulnerability allows middleware to be skipped by manipulating the value of the x-middleware-subrequest HTTP header, which surprised many people.

At the end of last year, apart from this vulnerability, another authentication bypass vulnerability in Next.js middleware, CVE-2024-51479, was disclosed.

This is the vulnerability I reported two years ago, where middleware protecting certain paths can be bypassed.
Its impact is similar to that of CVE-2025-29927, and I would like to highlight that there was another problematic parameter in Next.js besides x-middleware-subrequest.

Middleware Protecting Specific Paths

It is not uncommon to use middleware in Next.js to protect specific paths. In fact, in the sample code from Auth.js (NextAuth.js), a widely used Next.js authentication library, there is code that restricts access to the /admin path to administrators only.

https://github.com/nextauthjs/next-auth-example/blob/e8b0310f9c2f428c74e574b5b7375db8164b2f3a/middleware.ts

Also, Next.js middleware provides a configuration called config.matcher that applies middleware only to certain paths, so there are many implementations protecting specific paths with this setting.

https://nextjs.org/docs/app/building-your-application/routing/middleware#example

Since only one middleware is allowed in current versions of Next.js, the official documentation suggests using conditional logic within the middleware function to differentiate based on path.

https://nextjs.org/docs/messages/nested-middleware

Middleware Bypass via __nextLocale - CVE-2024-51479

While CVE-2025-29927 involves bypassing the middleware by exploiting the x-middleware-subrequest header, Next.js internally contains many other proprietary headers and queries.

The vulnerability CVE-2024-51479, disclosed last December, allows bypassing by appending a URL query called __nextLocale.

For example, consider middleware designed to block access to /admin (using Next.js version 14.2.14):

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // Block access to /admin and /admin/*
  return NextResponse.redirect('<http://example.com>')
}

export const config = {
  matcher: [ '/admin', '/admin/:path*' ],
}

However, if you access the URL  /?__nextLocale=adminthe middleware is bypassed, and the /admin page is returned to the client.

Request Path Tampering

Let’s look at another example.

This example middleware (in Next.js version 13.3.4), which does not use config.matcher, blocks access to /admin by checking request.nextUrl.pathname:

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  console.log('Middleware:', request.nextUrl.pathname)

  // Block access to /admin
  if (request.nextUrl.pathname === '/admin') {
    return NextResponse.redirect('http://example.com')
  }

  return NextResponse.next()
}

However, this middleware can also be bypassed if the URL contains the query /?__nextLocale=admin.

According to the server log, inside the middleware request.nextUrl.pathname becomes /admin/admin, and so it is not recognized as an access to /admin.

What is Happening

Using Next.js version 13.3.4 as an example, let me explain what occurs when __nextLocale is specified.

(Note: Behavior may vary depending on the Next.js version and environment.)

The __nextLocale query originally stores language settings like en or jp and is probably intended for use within Next.js internal routing. However, it was possible to specify this query from the HTTP request.

When accessing with the query __nextLocale=admin, Next.js first resolves the locale and searches for the /admin path as the target route.

Then, before rendering the /admin page, the middleware is executed.

Before executing the middleware, Next.js normalizes the URL, and during this normalization, the locale is resolved again.

https://github.com/vercel/next.js/blob/48323c9dfefc08eaf84d4ee077d345fe38a2dda8/packages/next/src/server/next-server.ts#L2119

    if (this.nextConfig.skipMiddlewareUrlNormalize) {
      url = getRequestMeta(params.request, '__NEXT_INIT_URL')!
    } else {
      // For middleware to "fetch" we must always provide an absolute URL
      const query = urlQueryToSearchParams(params.parsed.query).toString()
      const locale = params.parsed.query.__nextLocale

      url = `${getRequestMeta(params.request, '_protocol')}://${
        this.hostname
      }:${this.port}${locale ? `/${locale}` : ''}${params.parsed.pathname}${
        query ? `?${query}` : ''
      }`
    }

Due to this normalization, the middleware sees the URL as /admin/admin instead of /admin.

Since /admin/admin is not protected, an attacker can bypass the middleware checks and access the /admin page.

Behavior Varies by Version

Moreover, the behavior changes depending on the Next.js version and the environment.

For example, when accessing  /?__nextLocale=admin to an app implemented with the App Router and Next.js version 14.2.14, the request.nextUrl.pathname used by the middleware becomes /admin/.

On the other hand, if you call /admin?__nextLocale=foobar, the middleware will get the path /foobar/admin, and the client will get the /admin page.

Conclusion

Although CVE-2024-51479 may affect fewer applications than CVE-2025-29927, which can completely bypass middleware, many implementations still rely on URL paths (request.nextUrl.pathname) or matcher configurations for authentication, authorization and security protection.

Since Next.js versions up to v14.2.14 and v13.5.7 are affected by the bypass issue using the __nextLocale query, it is recommended to upgrade.

Moreover, while the initial CVE stated that “it was possible for this authorization to be bypassed for pages directly under the application's root directory”, in practice, all pages are affected without such restrictions.

Timeline

  • 2023/04/10: Reported vulnerability via huntr.dev
  • 2023/05/08: Reported vulnerability directly to the Vercel team and triaged
  • 2024/10/02: After discussed with the Vercel team, I also reported this issue to the NextAuth.js team
  • 2024/10/04: A patch was applied
  • 2024/12/17: Vulnerability disclosed
シェア
X FaceBook
セキュリティ診断のことなら
お気軽にご相談ください
セキュリティ診断で発見された脆弱性と、具体的な内容・再現方法・リスク・対策方法を報告したレポートのサンプルをご覧いただけます。

関連記事

経験豊富なエンジニアが
セキュリティの不安を解消します

Webサービスやアプリにおけるセキュリティ上の問題点を解消し、
収益の最大化を実現する相談役としてぜひお気軽にご連絡ください。

疑問点やお見積もり依頼はこちらから

お見積もり・お問い合わせ

セキュリティ診断サービスについてのご紹介

資料ダウンロード