Next.jsのCVE-2025-29927という脆弱性情報はもうご存じでしょうか? Next.jsのMiddleware(ミドルウェア)で行っている認証・認可チェックを攻撃者にすり抜けられてしまう恐れがあるというのです。
結論から言えば、Next.jsをセルフホストで運用している場合は直ちにアップデートが必要になります。Next.js公式ブログでも「セルフホスト環境のユーザーは直ちにアップデートすべきだ」と強く呼びかけています。
本記事では、この脆弱性の影響範囲や深刻度、発生する仕組みと再現方法、そしてワークアラウンド(一時的な対処)や恒久的な対策について、分かりやすく解説します。
結論(先に要点)
- Next.jsのMiddlewareでの認可処理をバイパスされる恐れがある致命的な脆弱性です。攻撃者は細工したHTTPリクエストヘッダーを送るだけで、本来Middleware内で行われるはずの認証チェックをスキップさせることができます。その結果、未認証のユーザーが保護されたリソースにアクセスできてしまう可能性があります。
- 影響を受けるのは Next.js 15.2.2以下、および14.2.24以下のセルフホスト型アプリケーションです(後述の詳細なバージョン範囲参照)。Vercel等のホスティングサービス上のアプリは影響を受けません。
- 脆弱性の深刻度はCVSSスコア9.1(Critical)と評価されており、ネットワーク経由で認証不要・ユーザー関与不要で攻撃可能な非常に危険なものです。
- セルフホストでNext.jsを運用している方は、今すぐ安全なバージョンへアップデートしてください。アップデートが難しい場合でも、後述のワークアラウンドによる一時対策を直ちに講じることを強くおすすめします。
それでは、この脆弱性について詳しく見ていきましょう。
影響範囲:脆弱なバージョンと影響する環境
まず、この脆弱性の影響範囲を確認します。対象となるのはNext.js本体の特定バージョンであり、特にセルフホスト環境でMiddlewareを利用している場合に問題が生じます。
脆弱なバージョン
Next.js公式のセキュリティアドバイザリによると、この脆弱性は Next.js 11.1.4 から 13.5.6 までの全てのバージョン、および 14.0.0 から 14.2.24、15.0.0 から 15.2.2 のバージョンに影響します。要するに、Next.js 15.2.3未満および14.2.25未満のすべてのリリースが該当すると考えてよいでしょう。最新のパッチが当たった15.2.3および14.2.25より前のバージョンは、この問題を内包しています(後述の「恒久的な対策」で修正バージョンについて詳述します)。
影響する環境
特に注意が必要なのは、セルフホスト型でNext.jsアプリケーションを運用しているケースです。具体的には、開発済みのNext.jsアプリを自前のサーバで next start
コマンド(または output: 'standalone'
オプションでビルドしたサーバ)を使って動かしている場合が当てはまります。このようなセルフホスト環境でMiddleware機能を用いて認証・セキュリティチェックを行っている場合、本脆弱性の影響を強く受けます。もしMiddlewareで認可チェックを行い、その後のアプリケーション内部で再度検証していないような構成であれば、要注意です。
一方、影響を受けない環境もあります。Next.js公式によれば、Vercel社のプラットフォーム上でホストされているアプリケーションはこの問題の影響を受けません。同様にNetlify上でホストしている場合や、静的サイトとしてエクスポートしてデプロイしている場合(静的ファイルホスティングでMiddlewareが実行されない形態)は影響を受けないとのことです。実際、Vercel社は「当社プラットフォームのユーザーは影響を受けていない」と公式発表しています。これはおそらく、VercelやNetlifyのホスティング環境ではNext.jsのMiddleware実行方式やインフラ側のヘッダー処理により、この脆弱性が発現しないためだと考えられます。(とはいえ、ホスティング環境に関わらずNext.js自体のアップデートは推奨されています。)
まとめると
自己管理のサーバ上でNext.jsを稼働させている場合に本脆弱性の影響範囲に入ります。バージョンとしては概ね「Next.js 15.2.3未満または14.2.25未満(11系〜13系も含む)」が該当します。該当する方は次項以降を読みつつ、すぐに対策を検討してください。
脆弱性の仕組みと再現手順
では、具体的にこの脆弱性がどのような仕組みで発生し、攻撃者はどのようにそれを悪用できるのでしょうか。技術的な観点から深掘りしてみます。
内部ヘッダー x-middleware-subrequest
の悪用: Next.jsは内部的にx-middleware-subrequest
というHTTPヘッダーを使用しています。このヘッダーは、Middlewareからさらに別のリクエストを発行する際に無限ループを防ぐための目印として使われています。通常、Next.jsのMiddlewareでNextResponse.rewrite
やNextResponse.next()
によって別のルートに処理を渡すとき、再度Middlewareが呼び出されて無限再帰にならないように、この内部ヘッダーを付与して「これは内部からの再リクエストだからMiddleware処理はスキップして良い」という合図にしています。
ところが、今回の脆弱性ではこの内部ヘッダーの扱いに不備がありました。外部から来たリクエストであっても、x-middleware-subrequest
ヘッダーが付いているとNext.jsがそれを内部リクエストだと誤認し、本来実行すべきMiddlewareの処理をスキップしてしまったのです。セキュリティ報告によって、このヘッダーを細工することでMiddlewareの実行を意図的に飛ばせることが判明しました。つまり攻撃者はリクエストに特殊なヘッダーを付与するだけで、Middleware内の重要なチェック(例えば認証用のCookie検証など)を迂回できてしまったのです。
Next.js公式ブログの説明にもある通り、
“The security report showed it was possible to skip running Middleware, which could allow requests to skip critical checks — such as authorization cookie validation — before reaching routes.”
(「セキュリティ報告により、Middlewareの実行をスキップできてしまうことが判明しました。これにより、ルートに到達する前に認可用クッキーの検証といった重要なチェックをバイパスされる恐れがあります」)
再現シナリオ
それでは、どのようにこの脆弱性を悪用できるのか、具体例で考えてみましょう。例えば、以下のようにNext.jsのMiddlewareで認証をチェックしているアプリケーションがあるとします(Next.js 13以降でのmiddleware.ts
を想定):
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// 認証トークンの有無をチェック
const authToken = request.cookies.get('auth-token');
if (!authToken) {
// 未認証の場合はログインページへリダイレクト
return NextResponse.redirect(new URL('/login', request.url));
}
// 認証済ならそのまま次の処理へ
return NextResponse.next();
}
通常であれば、認証トークンを持たないユーザーが保護されたページ(例えば/admin
など)にアクセスしようとすると、このMiddlewareによって検知され、自動的に/login
へリダイレクトされます。ところが、攻撃者がHTTPリクエストに特別なヘッダーを付与するとこのチェックをすり抜けてしまいます。例えば以下のようなリクエストです。
GET /admin HTTP/1.1
Host: example.com
x-middleware-subrequest: 1
ここでx-middleware-subrequest: 1
というヘッダーが付いています。本来外部のクライアントが付与するものではない内部ヘッダーですが、Next.jsの脆弱なバージョンではこれが付いていると「内部からの再リクエストだな、ではMiddlewareはもう実行しなくていいだろう」と判断してしまいます。その結果、本来であれば先ほどのMiddlewareによってログインページに飛ばされていたはずの未認証リクエストが、そのままMiddlewareを経由せずに/admin
の処理に進んでしまうのです。もし/admin
ページ側で追加の認可チェックをしていなければ、攻撃者は認証なしで管理者ページにアクセスできてしまうことになります。
このように、攻撃者にとっては非常に簡単な手口で脆弱性を突くことができます。curl
やブラウザ拡張などでリクエストヘッダーを操作し、x-middleware-subrequest
という名前のヘッダーを付与すればいいだけです。しかも認証トークンや特権も一切不要ですから、悪意のある第三者がインターネット経由で直接攻撃可能です。セキュリティ研究者の分析によれば「x-middleware-subrequest: true
のように任意の値を入れたヘッダーを送りつけるだけ」でMiddlewareの検証が無効化されるとのことでした。まさにCVSS評価の通り「低い難易度でリモートから攻撃できる」脆弱性と言えます。
ワークアラウンド(一時的な対応策)
もし何らかの事情ですぐにNext.js自体をアップデートできない場合でも、一時的なリスク緩和策(ワークアラウンド)を講じることができます。公式アドバイザリでも、アップデートできない場合の回避策が提示されています。
“If patching to a safe version is infeasible, it is recommended that you prevent external user requests which contain the
x-middleware-subrequest
header from reaching your Next.js application.”
(「安全なバージョンへのパッチ適用が困難な場合は、x-middleware-subrequest
ヘッダーを含む外部からのリクエストがNext.jsアプリケーションに届かないようブロックすることを推奨」)
ポイントは問題のヘッダーを外部から受け付けないようにすることです。
具体的なワークアラウンドの例をいくつか挙げます。
-
リバースプロキシやWAFでヘッダーを除去/ブロックする: アプリケーションの前段にNginxやApacheなどのプロキシを置いている場合、
x-middleware-subrequest
というヘッダーがクライアントから送られてきたら削除したり、リクエストごと拒否したりする設定を入れるのが有効です。CloudflareなどのWAFサービスを使っている場合は、管理画面からこのヘッダーに対するルールを有効化できます。実際、Cloudflareは本脆弱性に対応するManaged WAFルールを緊急提供しました(現在は手動オプトイン方式)。該当サイトをCloudflare配下に置いている場合は、このWAFルールを有効にするだけで攻撃を遮断できます。 -
Next.js側でヘッダーをチェックしてブロックする: Next.jsのMiddleware自体で、このヘッダーが含まれていた場合に強制的にエラー応答を返すようなコードを入れてしまう方法です。例えば以下のような最上位Middlewareを追加します:
// security-middleware.ts (仮想的な例) import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { if (request.headers.has('x-middleware-subrequest')) { // 問答無用でブロック(ステータスコードは適宜403などに) return new Response('Forbidden', { status: 403 }); } return NextResponse.next(); }
これを全リクエストに適用すれば、攻撃者が細工したヘッダー付きリクエストを送ってきても常に403 Forbiddenで拒否できます。公式が推奨するのもこのアプローチで、外部からの
x-middleware-subrequest
を撥ねる簡易的なMiddlewareを挟むことで応急措置とするわけです。ただし、この方法を採る場合は将来アップデートした際に不要になるので、アップデート後にコードを戻し忘れないよう注意が必要です。 -
アプリケーション内で二重チェック: これは根本対策ではありませんが、万一Middlewareが抜けられても被害を軽減する策です。Middleware内だけで認可チェックを完結させず、実際のハンドラ(API RouteやページのgetServerSideProps等)側でも認証状態を確認するようにしておくと、たとえMiddlewareをすり抜けられても最終的な処理でブロックできます。理想的にはMiddlewareは利便性のためのファーストフィルターとし、バックエンド側でも重要処理前に必ず認証トークンを検証する二段構えにしておくと安全性が高まります。
以上のようなワークアラウンドによって、アップデートまでの間のリスクを軽減することができます。特に、本番環境で今まさに稼働中のサービスがある場合、アップデート作業に時間がかかることもあるでしょう。その間に攻撃を受けては大変ですから、できる限り早く上記対策で「ヘッダー付きリクエストをブロックする壁」を設けてください。
恒久的な対策:アップデート方法と設定改善
ワークアラウンドはあくまで一時しのぎです。恒久的な解決策は、Next.js自体を脆弱性の修正が適用されたバージョンにアップデートすることです。幸い、Next.js開発チームは本脆弱性に対処するパッチを迅速にリリースしました。では、そのアップデート手順や注意点をまとめます。
修正バージョンへのアップデート: 現在、以下のバージョンで本脆弱性が修正されています:
- Next.js 15系: 15.2.3 で修正(これ以降の15.xは安全)
- Next.js 14系: 14.2.25 で修正
- Next.js 13系: 13.5.9 で修正
もしあなたのプロジェクトが上記より古いバージョンを使用している場合は、該当する最新パッチバージョンにアップデートしてください。たとえば、package.jsonで"next": "15.2.3"
にバージョンを上げてからnpm install
(またはyarn install
)を実行し、アプリを再ビルド・再デプロイします。14系を使っている場合は14.2.25に、13系の場合は13.5.9にそれぞれ上げます。
なお、Next.js 12系など古いメジャーバージョンを使っている場合は公式のパッチ提供がありません(執筆時点ではv12向けのbackportも準備中とのこと)。この場合、将来的なことも考えて思い切って14系か15系へのメジャーアップグレードを検討したほうが良いでしょう。メジャーアップデートには互換性確認など工数がかかりますが、セキュリティには代えられません。どうしても難しければ前述のワークアラウンドで凌ぎつつ、早めに最新安定版への移行計画を立てることをおすすめします。
アップデート後の検証: アップデートが完了したら、念のため脆弱性が確かに解消されたか検証しましょう。例えば先ほどと同じようにx-middleware-subrequest
ヘッダー付きリクエストを送ってみて、本来Middlewareでブロックされるはずの未認証アクセスが通らなくなっていればOKです。Next.js 15.2.3以降では、この内部ヘッダーにランダムなIDが付与されて正当な場合しかMiddlewareをスキップしないよう修正されています。アップデート後は外部から適当なヘッダーを付けてもMiddlewareが実行される(つまり攻撃が効かない)状態になっているはずです。
セキュリティ設定の見直し: 恒久対策としてアップデートするだけでなく、これを機にアプリケーションのセキュリティ設定全般を見直すことも有益です。例えば:
- 信頼できないヘッダーをそもそもアプリに渡さないプロキシ設定になっているか(今回のような内部ヘッダー以外にも、
X-Forwarded-*
など偽装されると困るヘッダーがあります)。 - Middlewareに限らず重要な認可ロジックは複数箇所で検証する仕組みを取れているか(単一点の欠陥で全て突破されないように)。
- 定期的に依存ライブラリのアップデートやセキュリティ監査を行っているか。
Next.jsは比較的アップデート頻度も高く、特にセキュリティリリースがあった場合は素早く適用する習慣をつけると良いでしょう。npmやGitHubのDependabotアラートでも、今回のような既知の脆弱性について警告が出るはずです。実際、GitHub上では本脆弱性に対するAdvisory(GHSA)が公開されており、該当バージョンを使っているリポジトリにはアラートが届く仕組みになっています。こういった通知を見逃さないようにするのも大切ですね。
その他の観点(Vercelとセルフホストの違い、攻撃事例、対応状況など)
最後に、今回の脆弱性に関連するその他のトピックをいくつか補足します。
なぜVercelでは影響がなかったのか?
先述の通り、Vercel社の公式声明では「Vercel上のNext.jsアプリはこの脆弱性の影響を受けない」とされています。その理由を推測すると、Vercelのプラットフォームではx-middleware-subrequest
ヘッダーを外部から付与しても、除去される対策が速やかになされたか、ミドルウェアの無限ループ呼び出しを防ぐ機構がプラットフォーム独自にもともと実装されていた可能性があります。
もっとも、Vercelチームも「影響はないが早めにアップデートはしてください」と案内しており、根本的にはアプリ側をアップデートしておくに越したことはありません。
Cloudflare WAFの素早い対応
脆弱性公表から間もなくしてCloudflareが自社WAFにNext.js向けの保護ルールを追加しました。初期状態では一部誤検知の報告があったため現在はデフォルト無効(手動有効化)となっていますが、こうした迅速なセキュリティコミュニティの対応はありがたいですね。大規模なCDN/WAF事業者がグローバルに防御策を講じたことで、脆弱なままのサイトであってもCloudflare経由なら攻撃を防げているケースもあるでしょう。
まとめ
CVE-2025-29927(Next.jsのMiddleware認可バイパス脆弱性)について、その概要から対策までをご説明しました。重要なポイントを振り返ると:
- Next.jsの特定バージョンにおいて、Middlewareでの認可チェックが意図せずスキップされてしまう重大な欠陥が見つかりました。【※】
- セルフホスト環境でNext.jsを稼働させている場合に影響し、該当バージョンを使っているサイトは緊急にアップデートが必要です。
- 脆弱性の深刻度は最高クラスで、攻撃者は細工したヘッダーを付けるだけで未認証アクセスを通せてしまう危険があります。
- 対策としては、最新の修正バージョン(15.2.3/14.2.25など)へのアップデートが最優先です。アップデートできない場合でも、
x-middleware-subrequest
ヘッダーをブロックする一時的ワークアラウンドを今すぐ実施してください。 - VercelやNetlifyなどのホスティング利用者も油断せず、依存パッケージのアップデートやセキュリティ情報のフォローを欠かさないようにしましょう。コミュニティ全体で今回の教訓を活かし、より強固なセキュリティ対策を心がけたいですね。
幸い大きな被害は報告されていないとはいえ、油断は禁物です。この記事をご覧になった皆さんも、自分のプロジェクトを今一度チェックし、必要ならばすぐに対応してください。
参考リンク