React 19 / Next.js 15 のパッチ脆弱性 (CVE-2025-55182 / 55183 / 55184) を手動追跡で素早く対応した話
TL;DR
- React Server Components 起因の CVE が連続公開されたとき、公式 Blog / Security Advisory の直接購読が最速の検知経路になった
- Dependabot や
npm auditは有用だが、データベース反映や対象範囲判定にタイムラグが出ることがある - 小規模チームでは、公式情報の手動追跡 +
npm outdated+ patch bump の定型手順でも 24 時間以内の対応目標を満たせる - patch bump 後も addendum や追加 advisory が出るため、公開直後の数日は継続ウォッチが必要になる
概要
React 19 / Next.js 15 の App Router 環境で、React Server Components 関連の CVE に短時間で対応した運用事例です。Dependabot を使わず、公式アドバイザリ購読と手動確認を中心にした場合のメリット・限界・再発防止策を整理します。
対象読者は、React / Next.js のセキュリティアップデートを小規模チームで追っている開発者、または Dependabot だけに頼らない脆弱性対応フローを作りたいチームです。
目次
- 状況 / 課題
- 候補 / トレードオフ
- 採用案と理由
- 実装抜粋
- 運用上の学び
- 振り返り
- まとめ
- 参考
状況 / 課題
2025 年 12 月、React Server Components (RSC) の実装に 3 件の脆弱性が相次いで公開された。CVE-2025-55182 (CVSS 10.0 RCE) は 12 月 3 日、CVE-2025-55183 (ソースコード露出 / Medium) と CVE-2025-55184 (サービス妨害 / High) は 12 月 11 日の公開である。
対象プロジェクトは React 19 + Next.js 15 の App Router を本番で運用しており、すべての脆弱性が対象範囲に含まれた。「24 時間以内にパッチ適用」という運用目標を、Dependabot や CI 自動化なしでどう達成したか、その判断プロセスを振り返る。
| 項目 | 内容 |
|---|---|
| ワークロード特性 | React 19 + Next.js 15 を本番運用中の SPA (App Router 使用) |
| SLA / 可用性 | セキュリティパッチは 24 時間以内の適用を目標にする |
| コスト制約 | Dependabot 導入コストを避けたい小規模チーム |
| 期限 | CVE 公開から 1 日以内に patch bump 完了 |
脆弱性の概要
CVE-2025-55182 (CVSS 10.0 — RCE)
React Flight プロトコルのデシリアライズ処理に起因するプロトタイプ汚染から、任意の JavaScript がサーバー上で実行される可能性がある。Next.js 15.x / 16.x の App Router が対象。
CVE-2025-55184 (High — DoS)
React 公式ブログが次のように説明している:
"A malicious HTTP request can be crafted and sent to any Server Functions endpoint that, when deserialized by React, can cause an infinite loop that hangs the server process and consumes CPU."
— Denial of Service and Source Code Exposure in React Server Components — React Blog
CVE-2025-55183 (Medium — ソースコード露出)
同ブログでは次の点が強調されている:
"Only secrets in source code may be exposed, but runtime secrets such as
process.env.SECRETare not affected."— Denial of Service and Source Code Exposure in React Server Components — React Blog
つまり process.env 経由のランタイム環境変数は露出しないが、ソースコード中にハードコードされた秘密情報は漏洩しうる。なお NEXT_PUBLIC_ プレフィックスの変数やビルド時に静的インライン化された値はバンドルに焼き込まれるため、この限りではない点に注意が必要だ。
候補 / トレードオフ
候補 A: Dependabot による自動 PR
- 特徴: GitHub が自動で PR を起票し、パッチバージョンへの bump を提案する
- 長所: ゼロオペで検知・PR 作成まで完了する。Advisory 公開からのタイムラグが最小
- 短所: breaking change を含むパッチでも自動 merge されうる。false positive のレビューコストが積み重なる。Pages Router / App Router 混在プロジェクトでは影響範囲の判断が Dependabot には難しい
- 見積コスト: セットアップコスト低、レビューコスト中〜高 (大規模 deps では PR 量が増大)
Dependabot の検知メカニズムについて、GitHub 公式ドキュメントはこう説明する:
"Dependabot scans any push, to the default branch, that contains a manifest file. When a new advisory is added, it scans all existing repositories and generates an alert for each repository that is affected."
— Troubleshooting the detection of vulnerable dependencies — GitHub Docs
イベント駆動で動作するため理論上は高速だが、PR を自動 merge するには追加の設定と信頼が必要になる。
候補 B: npm audit の CI 組み込み
- 特徴: CI が失敗することで脆弱性を検知する
- 長所: セットアップが単純。既存 CI パイプラインに 1 行追加するだけ
- 短所: PR / push タイミングでしか走らない。advisoryデータベースへの登録ラグがある。npm 公式ドキュメントが示す通り peerDependencies は対象外になる
npm 公式の説明:
"
npm auditchecks direct dependencies, devDependencies, bundledDependencies, and optionalDependencies, but does not check peerDependencies."— Auditing package dependencies for security vulnerabilities — npm Docs
- 見積コスト: セットアップコスト最低、CI 時間増加あり。push のない日は検知されない
候補 C: 公式 advisory 手動購読 + 毎日 npm outdated
-
特徴: 公式ソース (GitHub Security Advisories / React blog / Next.js blog) を RSS またはメールで購読し、毎日
npm outdatedで差分確認する - 長所: 公式 1 次ソースを直接購読するため、Dependabot のデータベース登録ラグを排除できる。影響範囲の判断を人間が行うので false positive による無駄なマージ作業が生じない
- 短所: 購読設定とチェック習慣のコストが個人に依存する。チームが大きくなると属人化しやすい
- 見積コスト: セットアップコスト最低、判断コスト中 (脆弱性の影響判断は知識が必要)
採用案と理由
採用: 候補 C (公式 advisory 手動購読 + 毎日 npm outdated)
理由:
- 公式情報の即時性: Next.js の公式セキュリティアップデートページが CVE 公開当日に対応バージョンを列挙した。Dependabot のデータベースに登録されるよりも早く情報を得られた
- 影響範囲の正確な判断: App Router を使用している場合のみ影響を受けるという条件を、Dependabot は自動判定できない。公式アドバイザリを読んで人間が判断することで不要な対応を省けた
-
breaking change のない patch bump: Next.js 公式アドバイザリが
npm install next@15.X.Yの形式でピンポイントのコマンドを提示しており、CI を壊さずに即日適用できた
Next.js 公式セキュリティアップデートはこう述べている:
"All users should upgrade to the latest patched version in their release line. There is no workaround. Upgrading to a patched version is required."
実装抜粋
# 毎日の確認スクリプト例 (ローカル手動実行用)
#!/bin/bash
set -euo pipefail
echo "=== npm outdated ==="
npm outdated || true # 差分があっても exit 1 にしない (確認目的のため)
echo "=== npm audit ==="
# ローカル確認用: || true で終了コードを握り潰し、出力だけ確認する
# ※ CI に組み込む場合は || true を取り除き、脆弱性検知でビルドを失敗させること
npm audit --audit-level=high || true
公式アドバイザリが出た当日に実行した patch bump コマンド (Next.js 15.1.x を使用していた場合の例):
# CVE-2025-55182 (12/3 公開 RCE) のパッチ
npm install next@15.1.9
# CVE-2025-55183 / 55184 (12/11 公開) のパッチ — 55182 の修正も内包
npm install next@15.1.11
npm install react@19.1.5 react-dom@19.1.5
実際の手順では、12/3 に next@15.1.9 にあげ、12/11 に追加で next@15.1.11 に更新した。最新のパッチバージョンについては Next.js 公式セキュリティアップデート を参照すること。
bump 後は package-lock.json をコミットし、CI では npm ci (= ロックファイル厳守インストール) に切り替えることで、本番環境に確実にパッチバージョンが適用される。なお Next.js は内部に next/dist/compiled/react としてビルド済みの React を持つため、React 単体を更新するだけでなく Next.js 本体の更新が必須であることにも注意が必要だ。
運用上の学び
タイムライン (CVE-2025-55182 / 55183 / 55184 の場合)
| 日時 | アクション |
|---|---|
| 12/3 AM | CVE-2025-55182 (RCE CVSS 10.0) の Next.js Security Advisory 公開 |
| 12/3 AM (30 分以内) | メール購読で検知 → GHSA-9qr9-h5gf-34mp の本文を確認 |
| 12/3 午前中 |
npm outdated で該当バージョン差分確認 → next@15.1.9 に bump |
| 12/3 午後 | ローカル動作確認 → CI 通過 → deploy 完了 (SLA 達成) |
| 12/11 AM | CVE-2025-55183 / 55184 の React Blog / Next.js Blog 公開 |
| 12/11 AM (30 分以内) | メール購読で検知 → 追加アドバイザリを確認 |
| 12/11 午前中 |
next@15.1.11 + react@19.1.5 に追加 bump → CI 通過 → deploy |
CVE-2025-55184 の初回修正は不完全だった
Next.js 公式は後日こう補足している:
"Addendum: The initial fix for CVE-2025-55184 was incomplete. A complete fix has been issued under CVE-2025-67779. If you previously upgraded to one of the initially recommended versions, please upgrade again to the latest patched versions listed below."
これは公式アドバイザリの継続ウォッチが重要であることを示す。Dependabot は「初回 bump で完了」と扱いやすいが、手動購読であれば addendum にも即座に気づける。
振り返り (ディレクター視点)
- 判断時に重視した軸: 「公式の 1 次情報を最も早く得られるか」「影響判断を自分たちで行えるか」の 2 点。自動化は便利だが、CVE の影響範囲判断 (App Router か Pages Router か、など) は文脈依存であり人間の確認が不可欠だった
-
どこを譲歩したか: チェックの習慣化は個人のモチベーションに依存する部分がある。カレンダーリマインダーと Slack への週次
npm outdated結果投稿で補完した。またnpm auditはpeerDependenciesをスキャン対象外とするため、手動での確認や追加ツール (npm ls --all等) で補う必要がある - もう一度判断するなら: チームが 5 人以上になったら「Dependabot の Vulnerability Alerts (アラート通知のみ) を有効化し、自動 PR / 自動 merge は無効のまま」という折衷案が有効。公式ブログの目視よりも確実なトリガーになりつつ、auto-merge のリスクを回避できる。今回のフローは 3 人以下の小規模チームに最適化されている
まとめ
- React 19 / Next.js 15 の CVE-2025-55182 (12/3) / CVE-2025-55183・55184 (12/11) は 2025 年 12 月に相次いで公開された RSC 起因の脆弱性
- 公式 Blog / Security Advisory のメール購読が最速の情報源。Dependabot のデータベース登録よりも早い場合がある
- patch bump 後も addendum が出る場合があるため、公開後数日は公式アドバイザリを継続ウォッチする
- 小規模チームでは「毎日 npm outdated + 公式購読」が運用コスト最小で SLA を満たせる現実的な選択肢
参考
公式 1 次資料
- Next.js セキュリティアップデート: 2025 年 12 月 11 日版 — Next.js Blog — CVE-2025-55183 / 55184 の Next.js 公式アドバイザリ (影響バージョン表・修正コマンド含む)
- React Server Components の DoS とソースコード漏洩を解説 — React Blog — React チームによる CVE-2025-55183 / 55184 の原典説明
- React Server Components に RCE 脆弱性 — GitHub Advisory GHSA-9qr9-h5gf-34mp — CVE-2025-55182 (CVSS 10.0 RCE) の Next.js 公式アドバイザリ
関連 issue
- Server Components を悪用した DoS 攻撃 — GHSA-mwv6-3258-q52c — CVE-2025-55184 (DoS High) の Next.js 側アドバイザリ
- Server Components DoS の修正が不完全だった件 — GHSA-5j59-xgg2-r9c4 — CVE-2025-55184 初回修正の不完全性を補う CVE-2025-67779 のアドバイザリ
- Server Actions からソースコードが漏洩する脆弱性 — GHSA-w37m-7fhw-fmv9 — CVE-2025-55183 の Next.js 側アドバイザリ
補足解説
-
パッケージの脆弱性を
npm auditでどう検出するか — npm Docs —npm auditの仕組みと peerDependencies の対象外ルール - Dependabot が脆弱性を検出しないときのトラブルシューティング — GitHub Docs — Dependabot のスキャントリガーと検知タイムラグの説明
- GitHub Advisory Database とはなにか — GitHub Docs — GitHub Advisory Database の構成と npm advisory との関係
