Next.js 脆弱性13件を実務で選別:本当に危険なRSCキャッシュ汚染

2026年5月のNext.js 脆弱性13件を、Vercel・Cloudflare環境での到達条件から実務的に整理。話題のWebSocket SSRFよりRSCキャッシュポイズニングを優先すべき理由、16.2.6/15.5.18への更新、デプロイ後のキャッシュパージ、認証・CSPの再テスト手順まで解説します。

Friday, September 4, 2026Omid Saffari
Next.js 脆弱性13件を実務で選別:本当に危険なRSCキャッシュ汚染

Threadsで広まっているスクリーンショットは、クラウドのメタデータエンドポイントまで到達するWebSocket SSRF、CVE-2026-44578のものです。私の構成ではこの経路に到達できず、真っ先に警戒すべき問題でもありません。本当に警戒すべきNext.js 脆弱性は、読者が見るあらゆるページを汚染しかねないのに、誰もスクリーンショットを投稿していないModerateの脆弱性です。

Next.js 脆弱性の要点と、本当に必要なトリアージ

Next.jsは2026年5月6日に13件のセキュリティアドバイザリを一斉公開し、5月7日に修正版の16.2.6と15.5.18をリリースしました。報道が集中したのはWebSocket SSRFのCVE-2026-44578です。スクリーンショットとして映えるからでしょう。攻撃者が接続をアップグレードすると、サーバー自ら169.254.169.254へアクセスし、メタデータエンドポイントからIAM認証情報が返ってきます。確かに衝撃的です。

ただし、影響するのはセルフホスト環境だけです。Cloudflareを前段に置いたVercel管理のデプロイでは、その経路に到達できません。私のサイトで読者に被害を及ぼし得るのは、ほとんど話題になっていないModerateのRSCキャッシュポイズニングです。汚染されたRSCレスポンスは攻撃者への応答だけで終わらず、共有エッジキャッシュに入り、タグをパージするまで全訪問者に配信されます。

Next.js >= 13.4.13を運用しているなら、今週中のアップグレードが必要です。判断すべきなのは、どのバージョンへ、どの順番で上げ、完了後に何を再テストするかだけです。以下は、App RouterをVercelで動かし、その前段にCloudflareを配置してCache-Tagによるパージと再検証用webhookを使うomidsaffari.comで、私が実施したトリアージです。これにより、優先順位は話題のCVEから大きく変わりました。

技術者ではない創業者が押さえるべきこと

プロダクトがNext.jsアプリなら、これはバックログに積む課題ではなく、今週対応する項目です。金銭的な問題として見るべきなのは、レイテンシや開発工数ではありません。汚染されたキャッシュページや認証を迂回された管理画面は、顧客からの信頼を損なう事故です。マーケティングページに攻撃者のコンテンツが表示されたスクリーンショットが1枚出る、あるいはセッションなしで誰かが/adminへ入れたという報告が1件出るだけで、翌週は販売ではなく説明に追われます。

エンジニアに確認する質問は一つだけです。「16.2.6または15.5.18へ更新済みで、デプロイ後にエッジキャッシュをパージしたか」。回答が「パッチ対応中」「進行中」「SSRFの影響はない」のように曖昧なら、作業は完了していません。セルフホスト環境(ECS、EC2、Kubernetesなど、自社管理のサーバーでnext startを実行する構成)は、ほかのすべての問題に加えてSSRFにもさらされるため、より高リスクです。自社がどちらに該当するかも尋ねてください。10秒で答えられるはずです。

13件を「自社環境に到達するか」で仕分ける

出回っている「13件のCVE、今すぐパッチを」という記事の誤りは、一覧を一律に扱っていることです。実際にはそうではありません。それぞれのアドバイザリには、セルフホスト、Turbopack、Cache Components、CSP nonce、i18nといった前提条件があります。現実に影響するのは、自社のデプロイ条件と一致するものだけです。ここでは同じ13件を、成立に必要な条件ごとに分類します。

ミドルウェアおよびプロキシ迂回のグループ(5件、ほとんどがHigh)。最大の問題はGHSA-267c-6grr-h53fで、App Routerのsegment-prefetch URLがミドルウェアの認証チェックをすり抜けます。このグループには、Turbopack向けに5月7日に公開された不完全修正への追加対応(GHSA-26hh-7cqf-hhc6)、Pages Routerのi18nデフォルトロケールパスを使った迂回、動的ルートのパラメータ注入による迂回も含まれます。前提条件は、認証やリライトの適用にNext.jsのミドルウェアを使っていることです。ほぼすべてのアプリが該当します。

SSRF、CVE-2026-44578。セルフホストサーバーのWebSocket upgrade handlerが、クラウドのメタデータを含むポート80の内部HTTPエンドポイントへ到達します。影響範囲は13.4.13+から<15.5.16、および16.0.0–<16.2.5で、セルフホスト環境のみです。Vercel管理のデプロイは影響を受けないことが確認されています。

**サービス拒否(DoS)**は2件です。一つは上流由来のRSC DoS、もう一つはCache Componentsを有効にしたアプリで発生するコネクション枯渇型DoS(High、GHSA-q4gf-8mx6-v5v3)です。後者の前提条件は、Cache Componentsを明示的に有効化していることです。大半のアプリは該当しません。

RSCキャッシュポイズニング(Moderate)。RSCペイロードの処理経路にあるキャッシュバスティングの衝突を利用し、細工したリクエストでキャッシュ済みレスポンスを汚染できます。前提条件は、CDN、リバースプロキシ、Vercelのエッジ、Cloudflareなど、下流のどこかでRSCレスポンスをキャッシュしていることです。私の構成で重要なのはこれです。

XSSは2件です。CSP nonceを生成するApp Routerアプリに影響するCVE-2026-44581(Moderate)と、信頼できない入力を受け取るbeforeInteractiveスクリプトのXSSです。前提条件は、nonce付きCSPを配信しているか、ユーザー入力をbeforeInteractiveのscriptタグへ渡していることです。

自社のデプロイが満たす前提条件を書き出してください。それが実際の対象リストです。omidsaffari.comでは、ミドルウェア迂回のグループ(該当)、SSRF(非該当、Vercelホスト)、RSC DoS(該当、上流由来)、Cache Components DoS(非該当、有効化していない)、RSCキャッシュポイズニング(該当し、影響も増幅)、CSP nonce XSS(該当)、beforeInteractive XSS(非該当)となります。High/Moderateの8件は、私に関係する5件まで絞り込めます。しかも、影響範囲が最も大きいのは有名な脆弱性ではありません。

話題のSSRFよりRSC キャッシュポイズニングを警戒すべき理由

CVE-2026-44578が成立するには、Node側のnext startサーバーがWebSocket upgradeを処理し、リダイレクトをたどる必要があります。Vercelでは、SSRFの経路が成立する形でリクエストがそのサーバーを通りません。プラットフォーム側でWebSocketを終端し、メタデータエンドポイントもIMDSv2の背後にあり、そのホップ制限では経路を通過できないためです。前段にCloudflareを置いても結論は変わりません。Vercel + Cloudflare構成では、あの衝撃的なスクリーンショットと同じ状況は再現しません。

一方、RSCキャッシュポイズニングでは事情が完全に逆転します。脆弱性はすべての利用者が通るリクエスト処理経路にあり、結果として汚染されるのはRSCペイロード、つまり読者へ届くシリアライズ済みのReactツリーです。私のサイトでは、そのペイロードは攻撃者へのレスポンスだけにとどまりません。ここに保存されます。

Http
Cache-Control: public, s-maxage=300, stale-while-revalidate=86400
Cache-Tag: article:nextjs-may-2026-security-triage

s-maxage=300により、Cloudflareはそのレスポンスを5分間保持します。stale-while-revalidate=86400により、期限切れ後もバックグラウンドで再検証しながら1日間配信を続けます。Cache-Tagはパージの仕組みです。新しい版を公開すると再検証用webhookがタグをパージし、オブジェクトが削除されます。

レスポンスが汚染された後の流れを追ってみます。攻撃者がキャッシュバスティングの衝突を悪用するルートへアクセスします。Cloudflareはキャッシュ可能なレスポンスだと判断し、そのURLのキャッシュキーで保存してarticle:<slug>を付与します。その後、そのスラッグを訪れる全員が、オリジンではなくエッジから汚染済みのRSCペイロードを受け取ります。後から追加したミドルウェアもWAFルールも通りません。汚染されたオブジェクトはすでに下流にあるからです。s-maxageの期間が切れるか、公開パイプラインがパージを実行するまで、300のPoPに残り続けます。すでにエッジにあるレスポンスに対して、オリジンのWAFルールは何の効果もありません。

だからこそ危険にさらされる資産は、内部APIではなく、公開コンテンツの表層であるコンテンツエンジンの出力です。13件のアドバイザリではSSRFがHigh、この問題がModerateに分類されています。しかし、キャッシュを前段に置いたRSCサイトでは、実務上の影響度は逆になります。

正しいアップデート手順とTurbopack追加修正の落とし穴

最初に、現在のバージョンを確認します。キャレット範囲を指定している場合、package.jsonだけでは実際に解決されたバージョンが分かりません。ロックファイルを確認してください。

Bash
bun pm ls | grep next
# or
npm ls next

次に、Next.js 16系なら16.2.6、Next.js 15系なら15.5.18へ固定します。16.2.5でも15.5.16でもありません。

Bash
bun add next@16.2.6
# or
npm install next@16.2.6 --save-exact

厳密なバージョン固定が必要なのは、ほとんど触れられていない落とし穴があるためです。当初の13件は、5月6日公開の16.2.5 / 15.5.16で修正されました。しかし5月7日、VercelはGHSA-26hh-7cqf-hhc6を公開しました。segment-prefetchによるミドルウェア迂回の修正が不完全で、Turbopack経由でリクエストを処理すると引き続き悪用できたためです。Turbopackを使わない環境は16.2.5 / 15.5.16で保護されましたが、Turbopack環境は保護されませんでした。完全な修正版は16.2.6 / 15.5.18です。

13.xまたは14.xを使用している場合、パッチは提供されません。Vercelはバックポートを行わないため、対策は15.xまたは16.xへの移行です。これはbun updateではなく、移行作業として見積もる必要があります。規模のあるアプリなら、少なくとも1週間を確保してください。特にミドルウェアのマッチャーとApp Routerのキャッシュ既定値には、無視できない破壊的変更の影響範囲があります。

デプロイが完了したら、エッジキャッシュをパージします。 今週読んだほかの記事では、この手順が抜けていました。パージしなければ、パッチ適用前にCloudflareがキャッシュしたRSCペイロードが残ります。攻撃可能な期間に誰かが悪用していれば汚染されている可能性があり、s-maxageの期限までエッジから配信され続けます。私の構成では次のように実行します。

Bash
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/purge_cache" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"purge_everything": true}'

続いて検証します。ミドルウェア認証で保護されたルートを一つ選び、アドバイザリに記載されたsegment-prefetch URLの形式を組み立てて本番環境へ再送します。未認証のリクエストに対し、ミドルウェアの仕様どおり401 / 302などが返るはずです。コンテンツ付きの200が返るなら、ミドルウェアのパッチが効いていません。Next.jsではなくデプロイの問題です。

16.2.6で変わった挙動を正直に確認する

正直に言えば、これはセキュリティ修正だけのアップデートではありません。脆弱性がルーティングとキャッシュキーの挙動そのものに存在したため、複数の修正がそれらを意図的に変更しています。したがって差分は発生します。

.rscとsegment-prefetch URLに対するミドルウェアマッチャーの厳格化。 segment-prefetchによる迂回の修正により、マッチャーの照合方法が変わりました。従来の形式を前提にしたマッチャーパターンがある場合は、改めて検証してください。特に、否定先読みで_nextパスを除外し、.rscは常にその配下にあると仮定していたケースが該当します。私は、保護されたルートのsegment-prefetchサフィックスを明示的に拾うよう、一つのマッチャーを広げる必要がありました。5分で直せる変更ですが、リプレイテストをしていなければ気づかないままサイレントなリグレッションになっていたはずです。

CSP nonceの処理。 XSS修正(CVE-2026-44581)により、App Routerのレンダリング内でnonceが伝播する仕組みが変わります。ミドルウェアでnonceを生成し、Scriptコンポーネントから参照している場合は、デプロイ後1日、CSPをreport-onlyモードで動かしてください。私の環境では違反は見つかりませんでしたが、挙動は実際に変わっています。また、ある1チームではnonce生成フローの更新が必要だったとも聞いています。

Cache Componentsの挙動変更。 コネクション枯渇型DoSの修正対象としてCache Componentsを利用しているなら、負荷時にキャッシュミスを集約する方法が変わります。ホットパスを再テストしてください。私はCache Componentsを使っていないため、対象外でした。

アップデート完了と判断する前に、私が実行した検証チェックリストは次のとおりです。

Text
[ ] next version pinned to 16.2.6 in lockfile
[ ] middleware auth replay on /admin via segment-prefetch URL  401
[ ] middleware auth replay via .rsc URL  401
[ ] RSC cache key sanity: same URL, two clients, identical payload
[ ] forced edge purge after deploy
[ ] CSP report-only on for 24h with no new violations
[ ] one full revalidate cycle on a high-traffic page

ステージングでの確認時間を確保してください。セキュリティ修正がルーティングとキャッシュキーの挙動を意図的に変えるため、リスクゼロのパッチ更新ではありません。火曜の午後に無事デプロイを終えられるか、火曜の夜にインシデント対応へ追われるか。その分かれ目は、本番環境へ切り替える前に認証経路をリプレイテストしたかどうかです。

WAFではなくパッチを適用する――構造から得る教訓

Vercelは今回のリリース向けWAFルールを提供していません。変更履歴には、完全な緩和策はパッチ適用だけだと明記されています。その判断は正しいものです。悪意あるリクエストの形式が正規のリクエストと大きく重なるため、エッジで安全にフィルタリングできるアドバイザリは一つもありません。Cloudflareは5月6日にWAFルールとフレームワークアダプターによる緩和策を提供しましたが、位置づけは**多層防御(defense in depth)**であり、アップグレードの代替ではありません。表現を正確に読めば、Cloudflareの変更履歴も、WAFルールはロールアウト期間中の露出を減らすもので、その後の代替策ではないと明記しています。

ここに、今週の出来事から得られる構造的な教訓があります。フレームワークをアップグレードし、再デプロイして、エッジキャッシュを同じ日の午後にパージできる構成なら、13件のCVEが同時公開されても火曜の作業項目として処理できます。それができない構成は、アップグレードに移行作業が必要、パージ手段がない、デプロイパイプラインに手動ゲートがあるといった理由で、ロールアウトが終わるまで危険にさらされます。数日、場合によっては数週間です。

これはAIエージェントの影響範囲に関する議論と同じ構図です。場当たり的なフィルタリングより、構造として素早く復旧できることが勝ります。すべての不正リクエストも、不正なエージェント呼び出しも防げるわけではありません。問題が一度起きても数分で対応でき、影響範囲を希望的観測ではなくトポロジーによって限定できるシステムを作るのです。

今夜アップデートしてください。16.2.6または15.5.18に固定し、その後キャッシュをパージします。心配すべきなのはスクリーンショットで話題のCVEではありません。キャッシュされたすべてのページに触れるModerateの脆弱性です。

Vercelでホストしていてもアップデートは必要ですか?

必要です。Vercelが無効化できるのはセルフホスト環境のSSRF(CVE-2026-44578)だけです。ミドルウェア迂回、RSCキャッシュポイズニング、DoS、XSSの各アドバイザリは、VercelでホストするApp Routerアプリにも該当します。

16.2.5 / 15.5.16で十分ですか? それとも16.2.6 / 15.5.18が必要ですか?

16.2.6 / 15.5.18へ更新してください。以前のビルドで当初の13件は修正されましたが、5月7日の追加アドバイザリ(GHSA-26hh-7cqf-hhc6)では、Turbopack環境にsegment-prefetchによる迂回が残っていました。

Next.js 14を使っています。パッチはどこにありますか?

パッチはありません。13.xと14.xには修正が提供されないため、唯一の対策は15.xまたは16.xへの移行です。単なるバージョン更新ではなく、移行作業として計画してください。

アップデートまでCloudflareやVercelのWAFルールでしのげますか?

多層防御としてのみ有効です。Cloudflareは5月6日にWAFとアダプターによる緩和策を提供しましたが、VercelはWAFルールを提供しておらず、完全な修正はパッチ適用だけだとしています。

キャッシュを前段に置いたRSCサイトで、本当に危険なアドバイザリはどれですか?

RSCキャッシュポイズニングです。s-maxageによりエッジでキャッシュされた汚染レスポンスは、Cache-Tagをパージするまで全訪問者に配信されます。

最終更新

2026年9月4日

カテゴリーBuild

Googleでこのサイトを優先する

omidsaffari.comをGoogle検索の優先ソースに追加

omidsaffari.comを優先ソースに設定すると、GoogleがTop Stories・AI Overviews・AI Modeであなたのために優先表示します。

ニュースレター

毎週日曜、一通の手紙。 動くシステムの話。感想戦ではなく。

AIベンチャーのポートフォリオ運営から生まれるビルドログ、稼働中のシステム、現場ノート。

週刊。スパムなし。いつでも解除できます。