React RCE 漏洞(CVE-2025-55182)– 問題與發生原因

2025 年 12 月初公布的 React Server Components 漏洞(CVE-2025-55182,亦稱 React2Shell / React4Shell)被評為 CVSS 10.0,在未經授權的情況下即可執行遠端程式碼(RCE)的極度嚴重問題。已經有公開 PoC 以及實際掃描與攻擊嘗試被觀測到。

本文將「誰、為何、危險程度」以更系統化的方式整理。


一目瞭然的摘要



  • 問題核心 React Server Components(RSC)使用的 Flight 協議反序列化邏輯缺陷,使得攻擊者能夠傳送被篡改的請求,導致伺服器執行任意 JS 代碼。

  • 受影響的主要組件

  • react-server-dom-webpack / -parcel / -turbopack 19.0 / 19.1.0 / 19.1.1 / 19.2.0
  • 內建於 Next.js 15.x、16.x、14.3.0-canary.77 之後版本(使用 App Router)

  • 僅在瀏覽器執行的「傳統 React SPA」 完全不使用 RSC/Server Actions/伺服器渲染的純客戶端 React 應用不受影響。

  • 對於曾使用 Next.js 的讀者,立即需要執行的步驟 1. 檢查專案中的 react-server-dom-* / next 版本 2. 將 React 升級至 19.0.1 / 19.1.2 / 19.2.1 或以上 3. 將 Next.js 升級至公告的修補版本(15.0.5、15.1.9、15.2.6、15.3.6、15.4.8、15.5.7、16.0.7 等)或降級至穩定版 4. 若伺服器已對外公開,請同時檢查日誌、WAF 規則與異常跡象


image

本次發現的漏洞是什麼

React 團隊公布的資訊整理如下:

  • 受影響對象:React Server Components(RSC)實作 (react-server-dom-*)
  • 漏洞區段:客戶端傳送 RSC 資料至伺服器時使用的 Flight 協議解碼(反序列化)邏輯
  • 攻擊方式
  • 攻擊者傳送 特製的 Flight 負載 至 RSC/Server Actions HTTP 端點
  • 伺服器「信任」此資料並在反序列化過程中,內部模組載入/物件建立邏輯被攻擊者輸入牽動
  • 結果,伺服器環境可執行任意程式碼(RCE)

關鍵在於,無需登入/會話(Unauthenticated)即可攻擊。若 Next.js RSC 伺服器對外公開,即「一旦開放於網際網路」即成為掃描與攻擊目標。


漏洞發生的精確條件



1. React/Next.js 版本條件

  • React RSC 相關套件
  • react-server-dom-webpack
  • react-server-dom-parcel
  • react-server-dom-turbopack

  • 受影響版本

  • 19.0、19.1.0、19.1.1、19.2.0

  • 修補版本

  • 19.0.1、19.1.2、19.2.1

  • Next.js(App Router 基礎)

  • 受影響:
    • 14.3.0-canary.77 以上
    • 15.x、16.x(包含 RSC 的基本 App Router 結構)
  • 修補:
    • 15.0.5、15.1.9、15.2.6、15.3.6、15.4.8、15.5.7、16.0.7 等

2. 架構/執行時條件

以下條件 全部滿足 時,攻擊可能性最高:

  1. 使用 RSC * Next.js App Router 或其他支援 RSC 的框架
  2. 伺服器執行 React 代碼 * Node.js 等環境下執行 React Server Components/Server Actions
  3. HTTP 對外公開 * 無論是網際網路或內部網路,攻擊者都能發送 HTTP 請求

相反地,以下環境與本漏洞幾乎無關

  • CRA/Vite 基礎的 純客戶端 React SPA
  • 完全不使用 RSC/Server Actions,僅將靜態 bundle 上傳至 S3、CDN 等
  • 「React 僅在瀏覽器執行,伺服器使用完全不同技術棧」的結構(例如 React + Django REST、React + FastAPI)

React‑DRF、React‑FastAPI 組合為何相對安全

將 React 與 Django REST Framework 或 FastAPI 等 Python 後端結合時,問題不會出現。原因如下:

  1. React 代碼不在伺服器執行 * React 僅在瀏覽器執行,Django/FastAPI 僅作為純 HTTP API 伺服器 * 伺服器不需要理解 Flight 協議,也不會解析 RSC
  2. 通訊邊界明確 * React ↔ 伺服器的通訊以 JSON/HTTP API 明確區分 * 伺服器不會 require() React 的「內部模組」,也不會根據客戶端傳遞的 metadata 來載入模組
  3. 不使用 RSC/Server Actions/Flight 協議 * 本次漏洞的攻擊面在於「伺服器端 React 代碼解析 RSC Flight 負載」 * Django/FastAPI 完全不包含此代碼

總結來說,「React + 伺服器整合框架(Next.js 等)」才是可能發生此類結構性問題的環境。分離的 React‑SPA + REST API 組合則不存在相關代碼路徑。


Flight 協議與伺服器端原型污染

更技術化地說,漏洞遵循「Flight 協議反序列化 → 原型污染 → RCE」的典型流程。

1. 受影響的程式碼模式

概念化的函式如下(示例):

// 受影響版本(概念程式碼)
export function requireModule<T>(metadata: ClientReference<T>): T {
  const moduleExports = parcelRequire(metadata[ID]); // 模組載入
  return moduleExports[metadata[NAME]];              // 直接使用客戶端輸入
}
  • metadata[ID]:決定載入哪個模組
  • metadata[NAME]:決定該模組的哪個 export

此處 metadata[NAME] 未經任何驗證直接使用。若攻擊者將其設為 __proto__constructor 等敏感鍵,便可在模組 export 之外,觸及物件原型鏈

2. 原型污染 → RCE

  • 伺服器程式碼在某處執行「普通物件建立」時,
  • 已被污染的 Object.prototype 屬性會自動附加
  • 若其中包含 spawnSync('sh') 等 shell 執行邏輯,
  • 透過新建立的物件即可執行程式碼
  • 攻擊者只需一次 HTTP 請求,即可達成遠端程式碼執行

具體修補內容

React 端的修補核心在於 「不再盲目相信客戶端傳遞的值」

最顯著的變更是 requireModule 函式:

// 修補後(概念程式碼)
export function requireModule<T>(metadata: ClientReference<T>): T {
  const moduleExports = parcelRequire(metadata[ID]);

  // 👇 確認 client 傳來的 NAME 為 moduleExports 的 own property
  if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
    return moduleExports[metadata[NAME]];
  }

  return undefined as any;
}

這一行即可阻止 __proto__constructor 等原型鏈關鍵字的存取,從而切斷 原型污染 → RCE 的攻擊向量。

修補還包含:

  • 加強 Flight 負載結構驗證
  • 限制特定危險欄位的使用
  • 在相關程式碼路徑加入額外防禦邏輯

核心在於「驗證」的加入。


Next.js 擴展 React 為伺服器時產生的結構衝突

React 本質上是「瀏覽器執行的 UI 函式庫」。

隨著 RSC 與 Server Actions 的出現,React 不再僅限於瀏覽器。

Next.js 將這些功能整合,打造:

  • 客戶端組件 + 伺服器組件 + 伺服器動作 的單一應用體驗
  • 但同時也讓「客戶端傳送的資料」能直接觸及伺服器模組載入/程式碼執行路徑

安全模型因此失衡。

前端假設被帶到伺服器的問題

前端環境通常:

  • 代碼 bundle 靜態且不可變
  • 模組載入在 編譯時決定,執行時不會改變模組名稱或 export 名稱

因此,

moduleExports[userInput]

在前端看似不太危險。

但在伺服器:

  • 輸入始終是 不可信的網路資料
  • 模組載入/物件建立直接關聯伺服器資源、檔案、進程
  • 任何將使用者輸入混入反序列化/動態載入的行為,都可能成為 RCE

需要的「新安全模型」包括:

  • Flight 負載結構的嚴格模式驗證
  • 客戶端可控值的白名單存取
  • HMAC 等請求簽名/完整性驗證
  • 以「RSC 伺服器永遠接收不可信輸入」為前提的設計

結論:前端與伺服器邊界模糊時,安全模型必須重新設計

React/Next.js 漏洞不僅是單一 bug,而是:

  • React 從前端庫演變為伺服器執行路徑,導致原有「前端信任模型」失效

傳統的 React + DRF/FastAPI 架構(「React 只在瀏覽器,伺服器僅提供 HTTP API」)不會出現此類漏洞。

相反,Next.js 這類 伺服器執行路徑深度結合 React 序列化/反序列化協議 的結構,必須同時設計功能與安全驗證。

未來「前端‑後端邊界消失」的框架將持續出現,這次事件提醒我們:便利性與安全邊界必須同步設計