対策・学習17分で読める

Next.js を安全に運用する:公開済みCVEに後れを取らないしくみ

Next.jsで最も大きなリスクは、公開済みのCVEを放置することです。実稼働版での判定、Dependabotやosv-scannerでの依存の自動監視、すぐ更新するルール、最小権限の4つで、後れを取らない運用の仕組みを解説します。

本文を読む
公開日
更新日
目次

対象:Next.js(や類似のJSフレームワーク)でアプリを作って公開している人。とくに「AIに手伝ってもらって作って、運用は手探り」という人向けです。実際の事故(→ 放置したCVSS 10.0の話)から抽出した、後れを取らないための4つの対策です。

当サイトの視点:大事なのは速さではなく、見落とさない仕組み

個人開発者がセキュリティでつまずく原因は、たいてい知識不足ではなく、運用を続けられないことです。CVE速報を誰より早く読むことに価値はありません(速さはベンダーやニュースに任せればいい)。効くのは 「自分に関係するCVEを、見落とさない仕組み」です。だからこの記事は、知識ではなく仕組みづくりを中心にしています。

1. 実稼働版で判定する

「危ないバージョンを使っているか」は、package.json の下限表記ではなく、実際に動いているバージョンで測ります。なぜなら、マニフェストの数字と実際に動く版はしばしば食い違うからです。

✗ package.json の下限で数える

"next": "^16.0.0" →「16.0.0が脆弱だから危険」と誤判定。「8個脆弱」と過大カウント。

✓ 実稼働版で数える

npm ls next で実際の解決版を確認 → 自動更新済みは安全、固定ピンだけ危険。本当は2個。

package.json の下限表記は、実際に動いている版と違うことがある。実稼働版で見ると危険度が変わる(実際に8→2に是正された)。
# 実際に解決されている版を確認
npm ls next react react-dom
# 稼働中コンテナの中で確認
docker exec <container> npm ls next

^16.0.0 のようなキャレット表記は、再ビルドで自動的に上がる範囲がある一方、固定ピンの依存は取り残されます。判定にはここに出るバージョンを使います。

自分の環境で確認する方法

ここからは、自分のアプリが今どの版で動いていて、既知のCVEに当たるかを確かめる手順です。どれも自分の環境の中を見るだけの操作です。

1

手元の版を確認する

プロジェクトのフォルダで npx next info を実行します。next・react・react-dom の実際のバージョンと、最新版との差が表示されます。npx next -v でも Next.js の版だけを確認できます。

2

なぜその版になっているかを確認する

npm ls next(pnpm なら pnpm why next)で、どのパッケージ経由でどの版が入っているかを見ます。ロックファイル(package-lock.json や pnpm-lock.yaml)をリポジトリに含めていない場合、ビルドのたびに版が変わり得るので、まず含めるようにします。

3

本番で動いている版を確認する

手元を更新しても、本番が古いイメージのまま動いていることがあります。コンテナなら、稼働中のコンテナの中で next の package.json に書かれた version を読みます(下のコマンド例)。output: 'standalone' の構成でも、この方法で確認できます。

4

既知のCVEと照合する

npm audit --omit=dev で、本番に入る依存だけを既知の脆弱性と照合します。--audit-level=high を付けると、High以上が見つかったときに終了コードが0以外になるので、CIで止める条件にできます。osv-scanner でロックファイルを検査する方法も同じ目的に使えます。

5

公式の勧告で、自分の構成が対象かを読む

Next.js の勧告は、App Router か Pages Router か、セルフホストかどうかで対象が分かれることがあります。勧告に書かれた修正版の一覧と、手順1〜3で確かめた版を突き合わせます。

# 手元:実際の版と最新版との差
npx next info
# 本番コンテナの中で動いている版
docker exec <container> node -p "require('next/package.json').version"
# 本番に入る依存だけを既知の脆弱性と照合(High以上で失敗)
npm audit --omit=dev --audit-level=high

動かし方で変わること

同じCVEでも、どう動かしているかで影響を受けるかが変わります。過去の2件を例に、動かし方ごとにまとめます。

動かし方ミドルウェアの認可迂回(CVE-2025-29927)RSCのRCE(CVE-2025-55182)更新の担当
Vercel・Netlify などのマネージド影響なし(ルーティングが別の仕組みで動くため)App Router なら対象。遮断ルールはあっても更新は必要自分(next の版は自分のロックファイルで決まる)
セルフホスト(next start/standalone、Docker含む)対象App Router なら対象自分(イメージの再ビルドと再起動まで)
静的エクスポート(output: 'export')影響なし(サーバーが動かないため)リクエストを受けるサーバーがないため、基本的に届かない自分(ビルドに使う依存は更新対象)

表から分かるとおり、マネージドのホスティングでも、Next.js の版を上げるのは利用者自身です。ホスティング会社の対策は、修正版に上げるまでの時間を稼ぐものと考えてください。

サポート期間も確認しておきます。公式のサポートポリシーでは、2026年10月時点で次のとおりです。

系列状態(2026年10月時点)セキュリティ修正
16.xActive LTS(新機能・修正・セキュリティ修正)出る
15.xMaintenance LTS(初回リリースから2年)重大なものだけ出る
14.x 以前サポート対象外深刻な場合にまれに出るだけで、保証はない

2. 依存を機械監視する

CVEを手作業で追い続けるのは難しく、その見落としが事故になります。ツールで自動監視します。

無料で始められる依存監視

# OSV スキャナでロックファイルを検査(CIに1ステップ)
osv-scanner scan -L pnpm-lock.yaml

GitHub なら Dependabot を有効化(リポジトリの Settings → Advanced Security → Dependabot alerts)。自分の依存に該当するCVEだけが自動でPR通知されます。

監視では優先度が肝心です。当サイトの考えでは、優先順位は「実際に悪用されているか(KEV)」と「CVSSの高さ」を掛け合わせて決めます。CVSSの数字が高くても未使用なら影響は小さく、中スコアでも悪用中なら最優先です。この優先度の判断が、運用の中心になります。

3. 更新:回避策ではなく修正版に上げる

脆弱性が見つかったら、フレームワーク本体を修正版へ更新して、脆弱性そのものを修正します。

表面的な対処(不十分)

  • リバースプロキシで攻撃に似たリクエストだけを遮断する
  • 課金や症状を止めて「対応完了」と考える
  • RCE の脆弱性自体は残ったまま

根本修正(正しい)

  • フレームワーク本体を修正版へ更新して脆弱性を修正する
  • 更新後、脆弱性の兆候が消えたかをログで確認
  • 被害拡大を止める作業と根本的な修正を、別作業として両方やる

やりがちな失敗

「課金や症状を止めた」≠「対応完了」。被害拡大を止めることと、脆弱性そのものを修正することは別の作業です。両方やって初めて完了です。

実際の例:2025年12月の React Server Components の脆弱性

公開済みCVEへの対応で何が起きるかを、2025年12月に公表された React Server Components(RSC)の脆弱性で振り返ります。いずれも React・Next.js の公式発表と CISA の公開情報にもとづきます。

  1. 2025年12月3日

    React が CVE-2025-55182(CVSS 10.0)を公表。認証なしでサーバー上のコード実行につながり得る脆弱性で、Next.js では App Router を使う 15.x・16.x などが対象(CVE-2025-66478)。Pages Router と Edge Runtime は対象外。回避策はなく、修正版(15.0.5/15.1.9/15.2.6/15.3.6/15.4.8/15.5.7/16.0.7 など)への更新が必要とされた。
  2. 2025年12月5日

    CISA が、実際に悪用が確認された脆弱性の一覧(KEV)に追加。
  3. 2025年12月6日

    Next.js が、12月4日13時(米国太平洋時間)の時点で修正前のまま公開していたアプリには、使っている秘密情報(APIキーなど)の入れ替えを強く勧めると追記。
  4. 2025年12月11日

    修正の検証の過程で、同じ仕組みに別の脆弱性が2件(サービス停止とソースコードの露出)見つかり、追加の修正版を公開。その後、サービス停止の修正が不完全だったとして CVE-2025-67779 が出され、先に更新した人にも再度の更新が求められた。

この例から、運用で押さえることが3つ分かります。

  • 一度更新しても終わりではない。同じ箇所の追加の修正が数日おきに続くことがある
  • ホスティング側の遮断ルールは補助で、版を上げることが唯一の完全な対処とされた
  • 修正前に公開していた期間があるなら、更新に加えて秘密情報の入れ替えまで行う

当サイトの視点:「更新した」ではなく「本番の版が修正版になった」で完了にする

この件のように追加の修正が続くと、「先週上げたから大丈夫」という記憶が当てになりません。完了の判断は、作業した記憶ではなく、本番で動いている版が最新の勧告の修正版以上になっているかで行います。当サイトも、デプロイ後にコンテナが作り直されたことと、中で動く版を確かめてから完了としています。

よくある間違いと直し方

  • package.json の数字だけで判断する:実際に入っている版は違うことがあります。npx next info や npm ls next で確かめます。
  • ロックファイルを更新しただけで終わる:本番のイメージを作り直して再起動するまで、古い版が動き続けます。本番の中で版を確認します。
  • 1回の更新で安心する:追加の勧告が続くことがあります。Dependabot などの通知を有効にしたまま、数日は勧告を追います。
  • ホスティング会社の遮断ルールに任せる:遮断ルールですべての攻撃の形を防げるとは限りません。版を上げます。
  • サポート対象外の系列に留まる:14.x 以前は修正が出る保証がありません。16.x へ移る計画を立てます。
  • 開発用の依存の警告が多すぎて、本番に関わる警告を見落とす:npm audit --omit=dev で本番に入る依存を先に見ます。
  • 修正前に公開していた期間を気にしない:その間に秘密情報が抜かれた可能性があります。APIキーやデータベースのパスワードを入れ替えます(→ .envとAPIキーの基本)。

4. 最小権限で被害の範囲を小さくする

万一悪用されても、被害が広がらない設計にします。

1

非特権ユーザーで動かす

コンテナの USER を root にしない。悪用されても、そのユーザーの権限の範囲までしか被害が及ばない。
2

DB・Redisは内部ネットだけに

外部公開せず内部ネットワークにバインド。直接到達できる面を減らす。
3

サービスごとに分離

ネットワークとデータをサービス単位で分け、1つの侵害が全体に波及しないようにする。

これらは、漏れたときに「コンテナ内のenv窃取で止まる」か「ホスト乗っ取りまで行く」かの分かれ目になります。

当サイト自身も同じ対策を実践している

当サイト自身も、ここで書いた通りに自分の依存をCVE監視の対象にしています。発端になった事故(公開済みCVSS 10.0の見落とし)を、二度と人が見落とさないよう、ツールによる自動監視を運用に組み込んでいます。私たちが「優先度(KEV+CVSS)で見る」と書くのは、自分たちがそう運用しているからです。

次に読む

出典

  • Next.js「Security Advisory: CVE-2025-66478」(2025年12月3日、12月6日追記): nextjs.org
  • Next.js「Security Update: December 11, 2025」(CVE-2025-55183/55184/67779): nextjs.org
  • NVD「CVE-2025-55182」: nvd.nist.gov / CISA「Known Exploited Vulnerabilities Catalog」: cisa.gov
  • Vercel「React2Shell Security Bulletin」: vercel.com
  • Vercel「Postmortem on Next.js Middleware bypass」(CVE-2025-29927): vercel.com
  • Next.js「Support Policy」: nextjs.org /「next CLI」: nextjs.org /「Static Exports」: nextjs.org
  • npm Docs「npm audit」: docs.npmjs.com / OSV-Scanner「Usage」: google.github.io / GitHub Docs「Configuring Dependabot alerts」: docs.github.com

よくある質問

QNext.js のセキュリティで一番大事なことは?
A

自分でバグを書かない以前に、『フレームワーク本体や依存の公開済みCVEを放置しない』ことです。多くの深刻な事故は新種の攻撃ではなく、既知の脆弱性の放置から起きています。

Q脆弱かどうかは package.json を見ればいい?
A

いいえ。package.json の `^` 表記(下限)は実態と違います。再ビルドで自動更新される範囲もあれば、固定ピンで取り残される依存もあります。必ず『実際に動いているバージョン』で判定してください。

Q個人開発で最初にやるべき1つは?
A

Dependabot(GitHub)か osv-scanner を有効化して、依存のCVEを自動で監視することです。人が手作業で確認すると、必ず見落としが出ます。仕組みで続けることが、知識より効きます。

Q自分のNext.jsのバージョンを確かめるには?
A

プロジェクトのフォルダで `npx next info` を実行すると、next・react・react-dom の実際のバージョンが表示されます。本番で動いているものは、稼働中のコンテナやサーバーの中で next の package.json の version を読んで確かめます(本文の手順3)。手元と本番の版が同じとは限らないため、両方を見るのが確実です。

QVercelなどのホスティングを使っていれば、更新しなくても大丈夫?
A

いいえ。2025年3月のミドルウェアの認可迂回(CVE-2025-29927)はVercelやNetlifyでは影響しませんでしたが、2025年12月のReact Server ComponentsのRCE(CVE-2025-55182)はApp Routerを使うアプリ全般が対象でした。Vercelは独自の遮断ルール(WAF)を入れたうえで、それだけでは全ての攻撃を防げないとして、修正版への更新を求めています。

QNext.js 14以前を使い続けても大丈夫?
A

おすすめしません。公式のサポートポリシーでは、14.x以前はサポート対象外で、セキュリティ修正は深刻な場合にまれに出るだけで保証はありません。2026年10月時点の対象は16.x(Active LTS)と15.x(Maintenance LTS)です。15.xの保守は初回リリースから2年とされているため、15.xを使っている場合も16.xへの移行を計画しておきます。