React2Shell (CVE-2025-55182) で気付いた React Server Components のセキュリティの盲点
はじめに
先日、Vercel から「Important Security Update for Next.js 15 & 16」という件名のメールが Gmail に届きました。
リンク先の CVE ページを確認したところ、CVSS スコアが 10.0(Critical) と記載されており、すぐに対応が必要な深刻な問題であることがわかりました。
CVSS スコアとは、脆弱性の深刻度を0.0〜10.0の数値で表す国際的な評価基準です。10.0はこのスケールの最大値であり、「認証なしで、リモートから、容易に、システムを完全に制御される可能性がある」レベルの脆弱性を意味します。過去に10.0を記録した脆弱性としては、2021年の Log4Shell(CVE-2021-44228) などがあり、いずれも業界全体に大きな影響を与えました[1]。
この脆弱性は React Server Components(RSC) に起因するもので、セキュリティ研究者の間では「React2Shell」と呼ばれています[2]。対応自体は依存パッケージのアップデートで完了しましたが、調査の過程で RSC のセキュリティ上の注意点について理解が深まりました。同じく Next.js を使用されている方の参考になればと思い、情報を整理します。
この記事で触れること / 触れないこと
触れること:
- CVE-2025-55182 の概要と影響範囲
- 問題発覚から修正までの時系列
- 自分のプロジェクトが影響を受けるかの確認方法
- 対応方法
- この問題から学べること
触れないこと:
- 攻撃手法の詳細な再現手順(悪用防止のため)
- RSCの内部実装の詳細
前提 / Versions
この記事は以下の環境についての情報を扱っています。
React関連パッケージ(脆弱なバージョン):
-
react-server-dom-webpack: 19.0.0, 19.1.0, 19.1.1, 19.2.0 -
react-server-dom-parcel: 同上 -
react-server-dom-turbopack: 同上
影響を受けるフレームワーク/バンドラー[3]:
- Next.js 15.x / 16.x / 14.3.0-canary.77 以降の canary 版
- React Router(RSCモード)
- Waku
- Expo
- Redwood SDK
- @parcel/rsc
- @vitejs/plugin-rsc
影響を受けるかどうかは、後述の「自分のプロジェクトは影響を受けるのか」セクションの確認方法を参照してください。
React Server Components の概要
RSCについて理解されている方は読み飛ばしてください。
React Server Components(RSC) は、サーバーでのみ実行されるコンポーネントを定義できる仕組みです。従来の SSR では、コンポーネントはサーバーで HTML にレンダリングされた後、クライアントでも再度実行されます(ハイドレーション)。一方、RSC の Server Components はサーバーでのみ実行され、そのコード自体はクライアントに送信されません。Next.js の App Router を使用している場合、デフォルトでこの機能が有効になっています。
'use client' ディレクティブはクライアント境界を定義し、そのファイルとそこからインポートされるモジュールはクライアントバンドルに含まれます。'use client' が付いていないコンポーネントでも、クライアントコンポーネントからインポートされた場合はクライアントで実行されます。
// Server Component
// app/users.jsx
async function ServerComponent() {
const data = await db.query('SELECT * FROM users');
return <div>{data.map(user => <p key={user.id}>{user.name}</p>)}</div>;
}
// Client Component
// app/counter.jsx
'use client';
function ClientComponent() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
サーバーとクライアント間のデータのやり取りには「Flight」と呼ばれるプロトコルが使用されています。今回の脆弱性は、このFlight プロトコルの実装に問題がありました。
CVE-2025-55182 とは
脆弱性の概要
CVE-2025-55182 は、React Server Components の Flight プロトコルにおける安全でないデシリアライゼーションの脆弱性です。
React 公式アナウンスによると、この脆弱性は「React が Server Function エンドポイントに送信されるペイロードをデコードする方法」に問題があり、認証されていない攻撃者が細工した HTTP リクエストを送信することで、サーバー上でリモートコード実行が可能な状態でした[4]。
重要な点として、アプリが Server Function エンドポイントを実装していなくても、React Server Components をサポートしている場合は脆弱になる可能性があります[4:1]。
Vercel のセキュリティアドバイザリには以下のように記載されています[5]:
A vulnerability in React's Flight protocol, used by frameworks such as Next.js, allows attackers to send maliciously crafted HTTP requests that are insufficiently validated, leading to Remote Code Execution (RCE) on the server.
影響を受けるバージョン
React関連パッケージ[4:2]:
-
react-server-dom-webpack: 19.0.0, 19.1.0, 19.1.1, 19.2.0 -
react-server-dom-parcel: 同上 -
react-server-dom-turbopack: 同上
影響を受けるフレームワーク/バンドラー[3:1]:
React 公式アナウンスによると、以下のフレームワーク/バンドラーが影響を受けます。
Next.jsの影響を受けるバージョン[6]:
- 15.x
- 16.x
- 14.3.0-canary.77 以降の canary 版
重要な点として、create-next-app で作成した Next.js 15.x/16.x アプリケーションは、デフォルト設定のまま脆弱です[7]。App Router がデフォルトで有効になっているため、意識せずに RSC を使用しているケースも多いと考えられます。
Wiz Research の調査によると、クラウド環境の約39%に脆弱なインスタンスが存在していたと報告されています[8]。
問題発覚から修正までの時系列
今回の脆弱性は、報告から公開まで迅速に対応されました[9]:
| 日付 | 出来事 |
|---|---|
| 2025年11月29日 | セキュリティ研究者 Lachlan Davidson 氏が Meta の Bug Bounty プログラムを通じて報告 |
| 2025年11月30日 | Meta Security が問題を確認、React チームが修正開発を開始 |
| 2025年12月1日 | Next.js、Vercel などフレームワークメンテナーとの調整開始 |
| 2025年12月3日 | CVE 登録、修正バージョン公開、セキュリティアドバイザリ公開 |
報告から公開まで4日間での対応となりました。
自分のプロジェクトは影響を受けるのか
確認方法
プロジェクトが影響を受けるかどうかを確認する手順を説明します。
1. 脆弱なパッケージを使用しているか確認
# React 関連パッケージの確認
npm list react-server-dom-webpack react-server-dom-turbopack react-server-dom-parcel
# Next.js のバージョン確認
npm list next
2. npm audit でチェック
npm audit
3. Next.js の場合:App Router を使用しているか
app/ ディレクトリが存在し、その中にページコンポーネントがある場合は、App Router(= RSC) を使用しています。
# app ディレクトリがあるか確認
ls -la app/
React 公式アナウンスによる判断基準
React 公式アナウンスでは、以下の場合はこの脆弱性の影響を受けないと述べられています[10]:
- アプリの React コードがサーバーを使用していない場合
- React Server Components をサポートするフレームワーク、バンドラー、またはバンドラープラグインを使用していない場合
重要: Server Function エンドポイントを実装していなくても、React Server Components をサポートしている場合は脆弱になる可能性があります[4:3]。判断に迷う場合は、アップグレードを推奨します。
対応方法
対応方法の詳細は、以下の公式セキュリティアドバイザリを参照してください。
- React: Critical Security Vulnerability in React Server Components
- Next.js: Security Advisory: CVE-2025-66478
要約
Reactパッケージの修正バージョン[11]: 19.0.1 / 19.1.2 / 19.2.1
Next.jsの修正バージョン[6:1]: 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6 / 15.4.8 / 15.5.7 / 16.0.7
Next.js 14.3.0-canary.77 以降の canary 版を使用している場合は、安定版 14.x にダウングレードしてください。
設定オプションで脆弱なコードパスを無効化する方法はありません[12]。アップグレードが唯一の対応方法です。
修正されたPRの内容
実際の修正内容について説明します。
React 本体の修正 PR: facebook/react#35277
修正の要点は、FlightReplyServer(クライアント→サーバー方向の通信)の実装を、以前ReactFlightClient(サーバー→クライアント方向)に対して行われた改善(PR #29823 および #33664)と同期させることでした[13]。PR 内でのコメントでも指摘されているとおり、今回の脆弱性への対応とその他の修正が単一の commit に含まれているため、根本的な問題の把握は(意図的に?)難しくなっています。
この問題から学べること
今回の脆弱性から得られる教訓を整理します。
1. 信頼できない入力データの処理は普遍的なリスクである
今回の脆弱性の本質は「信頼できない入力データの不適切な処理」です。これは React や Next.js に固有の問題ではなく、サーバーサイドでデータを処理するあらゆるシステムに共通するリスクです。
過去にも同様のパターンで深刻な脆弱性が発見されています。
-
Log4Shell(CVE-2021-44228): Java の Log4j ライブラリにおける JNDI Lookup 機能の悪用。ユーザー入力に含まれる
${jndi:...}のような文字列を解釈し、外部サーバーから悪意のあるコードをロードしてしまう問題 - Spring4Shell(CVE-2022-22965): Spring Framework におけるデータバインディングの問題。HTTP リクエストのパラメータを Java オブジェクトにバインドする際、ClassLoader への不正アクセスを許可してしまう問題
技術的なメカニズムはそれぞれ異なりますが、共通するのは「外部からの入力が、意図しない形でサーバー内部の機能を呼び出す経路になった」という構図です。フレームワークを使用する際は、どのような入力がサーバーで処理されるのかを意識しておくことが重要です。
2. 抽象化の利点とトレードオフ
RSC のようなアーキテクチャは、開発者体験を大幅に向上させます。サーバーとクライアントの境界を意識せずにコンポーネントを書けることで、開発効率が上がり、パフォーマンスの最適化も容易になります。
一方で、抽象化が進むほど「内部で何が起きているか」を把握しにくくなるのも事実です。今回の脆弱性では、Flight プロトコルという内部実装の詳細を知らなくても影響を受ける状態でした。
これは抽象化の欠点というよりも、抽象化を提供する側(フレームワーク)と利用する側(開発者)の責任分担の問題です。フレームワークは安全なデフォルトを提供する責任があり、開発者は使用しているツールのセキュリティ情報を追跡する責任があります。今回のケースでは、React チームが報告から4日という短期間で修正を完了しており、この責任分担がうまく機能した例といえます。
3. 迅速な対応を可能にしたエコシステム
今回の脆弱性対応で注目すべきは、報告から修正公開までわずか4日間で完了した点です[9:1]。この迅速な対応を可能にした要因を考えてみます。
- 責任ある脆弱性報告: 発見者の Lachlan Davidson 氏が Meta Bug Bounty プログラムを通じて報告し、公開前に修正の時間を確保できた
- 関係者間の連携: Meta Security、React チーム、Vercel、各ホスティングプロバイダーが協調して対応した
- WAF による暫定対策: Cloudflare や Google Cloud などが修正適用前の緩和策を提供した
オープンソースプロジェクトにおけるセキュリティ対応は、コミュニティ全体の協力によって成り立っています。利用者としても、脆弱性を発見した場合は適切なチャネルで報告することが、エコシステム全体のセキュリティ向上に貢献します。
4. 「デフォルトで安全」の難しさ
今回、create-next-app で作成したアプリケーションがデフォルト設定のまま脆弱であったことが話題になりました[7:1]。これは批判的に捉えることもできますが、別の視点もあります。
App Router がデフォルトで有効になっているのは、RSC のパフォーマンス上の利点を多くの開発者が享受できるようにするためです。セキュリティと利便性のバランスは常に難しい判断を伴います。
重要なのは、脆弱性が発見された際に迅速に修正が提供され、利用者に明確に通知されることです。今回のケースでは、Vercel からのメール通知、各種セキュリティアドバイザリの公開、ホスティングプロバイダーによる WAF ルールの展開など、多層的な対応が行われました。
5. 依存関係管理の重要性
現代の Web アプリケーションは多数の依存関係の上に構築されています。npm audit を実行すると、直接依存していないパッケージの脆弱性が報告されることも珍しくありません。
今回のケースでも、react-server-dom-* パッケージを直接使用していなくても、Next.js を通じて間接的に影響を受ける状態でした。
定期的な依存関係の確認を習慣化することを推奨します。
# 定期的に実行を推奨するコマンド
npm outdated # 更新可能なパッケージの確認
npm audit # 既知の脆弱性の確認
また、GitHub Dependabot のような自動化ツールを活用することで、脆弱性の検出と更新 PR の作成を自動化できます。
6. セキュリティ情報の追跡
使用しているフレームワークやライブラリのセキュリティ情報を追跡する仕組みを整えておくことで、緊急時の対応がスムーズになります。
- GitHub Security Advisories: GitHub が集約する脆弱性情報
- Next.js Security Advisories: Next.js 固有のセキュリティ情報
- 使用しているクラウドプロバイダーのセキュリティブログ
- npm/yarn のセキュリティ通知機能
今回の自分のケースでは、Vercel からのメール通知で脆弱性を知りました。使用しているサービスの通知設定を確認し、重要な情報を見逃さないようにしておくことが大切です。
まとめ
- CVE-2025-55182 は、React Server Components の脆弱性であり、CVSS スコア10.0の深刻な問題
- 認証なしでサーバー上で任意のコードを実行される可能性がある
- Next.js、React Router、Waku、Expo、Redwood SDK など、RSC を使用するフレームワーク/バンドラーが影響を受ける
- 対応は依存パッケージのアップグレードで完了(設定による無効化は不可)
- 報告から修正公開まで4日間で対応された
CVSS スコア10.0の脆弱性は、放置した場合のリスクが極めて高いです。該当するプロジェクトをお持ちの方は、早急な対応を推奨します。
参考文献
- Next.js - Security Advisory: CVE-2025-66478
- React - Critical Security Vulnerability in React Server Components
- Vercel - Summary of CVE-2025-55182
- GitHub - vercel/next.js Security Advisory
- Tenable - CVE-2025-55182: Frequently Asked Questions About React2Shell
- Wiz - Critical RCE Vulnerabilities Discovered in React & Next.js
- GitHub - facebook/react#35277
- FIRST.org - CVSS v3.1 Specification Document
-
Log4Shell (CVE-2021-44228) はCVSSスコア10.0と評価された。Wikipedia「Log4Shell」より。https://en.wikipedia.org/wiki/Log4Shell ↩︎
-
「React2Shell」という呼称はTenable社が命名。https://www.tenable.com/blog/react2shell-cve-2025-55182-react-server-components-rce ↩︎
-
React公式アナウンスに記載された影響を受けるフレームワーク/バンドラーの一覧。https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components ↩︎ ↩︎
-
React公式セキュリティアナウンス「Critical Security Vulnerability in React Server Components」より。https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components ↩︎ ↩︎ ↩︎ ↩︎
-
Vercel「Summary of CVE-2025-55182」より。https://vercel.com/changelog/cve-2025-55182 ↩︎
-
Next.js公式セキュリティアドバイザリ「Security Advisory: CVE-2025-66478」より。https://nextjs.org/blog/CVE-2025-66478 ↩︎ ↩︎
-
Wiz Research「Critical RCE Vulnerabilities Discovered in React & Next.js」より。https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182 ↩︎ ↩︎
-
Wiz Research調査結果。https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182 ↩︎
-
React公式アナウンスのTimelineセクションより。https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components ↩︎ ↩︎
-
React公式アナウンスより。https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components ↩︎
-
React公式アナウンス「Immediate Action Required」セクションより。https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components ↩︎
-
Next.js公式セキュリティアドバイザリより「There is no configuration option to disable the vulnerable code path.」https://nextjs.org/blog/CVE-2025-66478 ↩︎
-
GitHub PR #35277「Patch FlightReplyServer with fixes from ReactFlightClient」より。https://github.com/facebook/react/pull/35277 ↩︎
Discussion