
Next.js ミドルウェア認証バイパス
x-middleware-subrequest リクエストヘッダーを偽装することで、Next.js ミドルウェアの認証メカニズムをバイパスし、保護されたルートへの未承認アクセスを可能にします。
プロジェクトのソースコードはP神から引用されています。Next.js バージョンは 15.2.2 です(Next.js 15.x では、この問題は 15.2.3 で修正されました)。
Node と npm がインストールされていることを確認してください。以下のコマンドでバージョンを確認します:
node -v
npm -v
依存関係をインストールしてプロジェクトを起動
# 1. プロジェクトディレクトリに移動
cd vulenv
# 2. Yarn をグローバルにインストール(未インストールの場合)
npm install -g yarn
# 3. プロジェクトの依存関係をインストール
yarn install
# 4. 開発サーバーを起動
npm run dev
または一括で実行:
cd vulenv && npm install -g yarn && yarn install && npm run dev
成功すると以下のようになります:


VScode のデバッグ設定は以下の通り
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev"
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
},
{
"name": "Next.js: debug full stack",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev",
"serverReadyAction": {
"pattern": "- Local:.+(https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}
const run = withTaggedErrors(async function runWithTaggedErrors(params) {
var _params_request_body;
const runtime = await getRuntimeContext(params);
const subreq = params.request.headers[`x-middleware-subrequest`];
const subrequests = typeof subreq === 'string' ? subreq.split(':') : [];
const MAX_RECURSION_DEPTH = 5;
const depth = subrequests.reduce((acc, curr)=>curr === params.name ? acc + 1 : acc, 0);
if (depth >= MAX_RECURSION_DEPTH) {
return {
waitUntil: Promise.resolve(),
response: new runtime.context.Response(null, {
headers: {
'x-middleware-next': '1'
}
})
};
}
......
ミドルウェア関数は、再帰呼び出しの深さを検出し、無限ループ呼び出しを回避することを目的としています。そのメカニズムは、リクエストヘッダー x-middleware-subrequest に依存し、コロン : で複数のサブリクエスト名に分割し、現在のミドルウェア名 params.name と同じ出現回数(すなわち再帰の深さ)をカウントします。再帰の深さが設定されたしきい値(デフォルト MAX_RECURSION_DEPTH = 5)に達するか超えると、ミドルウェアは認証チェックなどのコアロジックをスキップし、リクエスト処理を続行します。
Tips:無限ループ呼び出しを回避するための大まかな意味は以下の通り
ユーザーが /dashboard にアクセス
↓
middleware がインターセプトし、/api/auth をリクエスト
↓
/api/auth が再度 middleware をトリガー
↓
middleware が再び /api/auth をリクエスト
↓
...
無限ループ!🌀
ミドルウェア名は middleware であり、以下のリクエストヘッダーを構築できます:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
上記の構築により depth = 5 となり、直接トリガーされます:
if (depth >= MAX_RECURSION_DEPTH)
アプリケーションが認証ロジックをミドルウェアに記述している場合、ミドルウェアは認証ロジックを終了し、以下を返します:
x-middleware-next: 1
これにより、リクエストはバックエンドに継続して流れ、認証されていない状態で保護されたリソースを取得できます。
以下の図の位置にブレークポイントを設定し(パスの詳細:CVE-2025-29927/vulenv/node_modules/next/dist/server/web/sandbox/sandbox.js)、デバッグを開始します。

Payload を送信

以下の図の位置でブレークがかかり、depth の値が 5 であることがわかります

実行を続けると、保護されたリソースを取得できます。

Pocsuite3 に基づいて作成されています。詳細は Poc_CVE-2025-29927.py を参照してください。

Next.js and the corrupt middleware: the authorizing artifact