React Flightプロトコルの武装化と防御:RSCにおける逆シリアライゼーションの脅威と対策
React Server Components(RSC)で使われるFlightプロトコルは効率的ですが、逆シリアライゼーションに潜むセキュリティリスクがあります。攻撃手法と防御策を詳しく解説します。
公開日時: 2026年8月25日 7:03 · 更新: 2026年9月27日 22:48
機械翻訳です。正確な内容は原文をご確認ください。新しい翻訳の作成にはログインが必要です(1日3回、本文などの合計24,000文字まで)。
はじめに
React Server Components(RSC)は、Reactアプリケーションの新たなパラダイムとして注目されています。コンポーネントをサーバーでレンダリングし、クライアントに送ることで、バンドルサイズの削減やデータ取得の効率化が期待できます。しかし、その通信プロトコルである「Flight」には、セキュリティ上の考慮が必要です。特に、クライアント側でFlightデータを元に戻す「逆シリアライゼーション」の処理が適切でない場合、攻撃者に悪用される可能性があります。本稿では、この問題を深掘りし、具体的な攻撃シナリオと防御策を紹介します。
RSCおよびFlightプロトコルの基礎
React Server Componentsは、サーバーサイドでコンポーネントをレンダリングし、その結果を特殊な形式でクライアントへ伝達します。この形式がFlightプロトコルです。FlightはJSONベースの拡張で、React要素やPromise(サスペンス)、さらにはサーバー関数への参照をエンコードできるように設計されています。クライアントは受け取ったデータを解析し、元のコンポーネントツリーを復元します。ここで使用されるのが、「逆シリアライザ」です。
Flightデータは通常、バイナリやテキストのストリームとして送信され、HTTPレスポンスのボディに埋め込まれます。クライアント側のJavaScriptがこれを解析するため、解析処理にバグや不適切な実装があると、セキュリティホールが生じます。
逆シリアライゼーションシンクとは
セキュリティ用語で「シンク(sink)」とは、情報の流れの中で、信頼できない入力が危険な操作に到達するための出口を指します。逆シリアライゼーションシンクは、シリアライズされたデータを復元する過程で、攻撃者が制御可能な値を渡すことにより、任意のコード実行やプロパティの書き換えなどが発生してしまう箇所です。
一般的な例として、JavaScriptの eval() 関数や、Functionコンストラクタ、プロトタイプの継承を利用した攻撃があります。Flightプロトコルの場合、データ内に「$」や「$$」などの特殊マーカーが含まれ、クラス参照や関数呼び出しが再構成されることがあります。もし、この再構成処理が安全でない場合、悪意のあるコードが挿入されるリスクがあります。
攻撃者がFlightプロトコルを悪用するパターン
具体的な攻撃手法をいくつか見てみましょう。
1. 通信の改ざん
サーバーとクライアント間のFlightデータが中間者攻撃などで改ざんされた場合、攻撃者はフェイクのコンポーネントデータを送り込むことができます。クライアント側で検証が不十分だと、任意のHTMLやJavaScriptを実行させられる恐れがあります。
2. プロトタイプ汚染
FlightデータがJSON.parseの結果に基づいてオブジェクトを生成する際、__proto__などのプロパティを含めることで、Objectのプロトタイプを変更できます。これにより、アプリケーションの動作を大規模に変えることが可能です。
3. サーバーコンポーネントの偽装
サーバーコンポーネントはクライアントに直接配信されないため、通常は詳細を知ることはできません。しかし、Flightプロトコルの構造を理解している攻撃者が、サーバーレスポンスを偽造し、意図したコンポーネントをレンダリングさせる可能性があります。
4. サプライチェーン攻撃
npmパッケージなどに悪意のあるコードが含まれている場合、そのパッケージがFlightデータを逆シリアライズすると、被害が拡大します。
安全な設計のための防御策
これらの脅威から身を守るには、以下のポイントに注意が必要です。
- 信頼境界の明確化:Flightデータは信頼できないものと仮定し、必ず検証を行う。
- スキーマバリデーション:受け取ったデータが期待する構造と一致しているかを確認する。
- 関数・クラス参照の排除:クライアント側で不要な関数やクラスを復元しない。どうしても必要な場合は、ホワイトリスト方式を採用する。
- プロトタイプ汚染対策:
JSON.parseを直接使わず、__proto__が現れたらエラーにする。 - ライブラリの最新化:React本体および関連パッケージを常に最新版に保ち、既知の脆弱性を解消する。
- CSPの適用:コンテンツセキュリティポリシーを設定し、万一攻撃されても悪影響を最小限にする。
実践的な監視とテスト
開発時には、専用のツールを使ってFlightデータを検証できます。例えば、React DevToolsのネットワークパネルでリクエスト内容を確認したり、カスタム検証関数をミドルウェアとして挿入することが考えられます。
// 悪い例:JSON.parseを直接使用
const obj = JSON.parse(flightData);
// プロトタイプ汚染の恐れ
// 良い例:カスタムの安全なパーサーを使用
function safeParse(data) {
if (data.includes('__proto__')) throw new Error('unsafe');
return JSON.parse(data);
}
セキュリティテストとしては、ファジング(fuzzing)により異常なFlightデータを送り、アプリケーションの挙動を監視する手法が有効です。また、Open SourceのSASTツールや、npm監査機能を活用して、依存関係の脆弱性を事前に検出しましょう。
まとめ
React Flightプロトコルは、効率的なUI配信を実現する一方、逆シリアライゼーションシンクが正しく管理されないと、重大なセキュリティインシデントにつながります。本稿で述べた対策を実践し、安全なRSC環境を構築してください。今後のReactアップデートでも、フレームワークとしてのセキュリティ強化が期待されますが、最終的な防衛はアプリケーション開発者の責任であることを忘れてはなりません。
Full stack 技術者