跳到正文
DEV Community· Yusuf Khalidd·· 32 分鐘前精選AI 評分83

如何檢查 Node.js 是否受 CVE-2026-111497 影響並修補 Brotli RCE

هل إصدار Node.js لديك مهدد بثغرة Brotli RCE؟ تحقق في دقيقتين

AI 導讀

Node.js Brotli RCE 漏洞 CVE-2026-111497 已有活躍利用,22.x、24.x、26.x 的修補版本下限分別為 22.23.4、24.22.1、26.12.1。

推薦理由

文章把版本檢查與實際 Brotli 解碼路徑分開,並比較多種 Node.js 框架及客戶端的行為,呈現判斷漏洞暴露面所需的兩個條件。

正文 · 繁體中文

你的 Node.js 版本是否受到 Brotli RCE 漏洞威脅?兩分鐘內檢查

هل إصدار Node.js لديك مهدد بثغرة Brotli RCE؟ تحقق في دقيقتين

立即執行此命令。如果你的版本低於下表所列的最低版本,Node.js Brotli 函式庫的遠端程式碼執行(RCE)漏洞(CVE-2026-111497)便會影響你,而且攻擊者已在利用此漏洞。

立即試用 Apidog

node -v
版本分支 受影響版本 修復版本由此開始 最新版本(2026 年 11 月 5 日)
26.x 低於 26.12.1 26.12.1 26.13.0
24.x 低於 24.22.1 24.22.1 24.22.2
22.x 低於 22.23.4 22.23.4 22.23.4
25.x, 20.x, 較舊版本 已結束支援:未修補,亦未評估 沒有可用修復版本 升級至 24 或 26

如要透過第二項指標確認,你可以直接查詢可執行檔:

node -p "require('node:zlib').constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH"

此更新加入了這個常數。我們已在三個受支援版本分支的九個 macOS 官方建置版本上執行該命令:每個已修補版本均出現 -17,而所有較舊版本均出現 undefined。不過,應先以 node -v 為準,因為部分採用回移植修補程式的 Linux 發行版可能不會加入這個常數。

忽略 process.versions.brotli;在 24.21.0 和 24.22.1 中,它均回傳 1.2.0;在 22.23.3 和 22.23.4 中,它均回傳 1.1.0。Node.js 團隊合併修復時沒有更改對外公佈的版本號,因此這個欄位無法顯示你的系統是否已取得修補程式。

快速摘要(TL;DR)

問題 答案
這是甚麼漏洞? Node.js 內置 Brotli 解碼器中的越界寫入漏洞,亦稱為 Node2Shell 或 HTTP2Shell
影響 應用程式崩潰、記憶體資料外洩,或遠端程式碼執行
嚴重程度 根據 Node.js,屬高危;根據 NVD,屬嚴重,評分為 9.8(CVSS 3.1)
目前是否有人利用此漏洞? 是。CISA 已於 2026 年 10 月 27 日將此漏洞列入已知遭利用漏洞目錄
是否需要登入? 不需要,根據 NVD 評分向量及 Akamai 的分析
哪些人面臨風險? 會解碼不可信 Brotli 資料的應用程式,例如 Express 5 請求本文、fetch() 回應,以及直接呼叫 node:zlib 函式庫的程式
解決方法 升級執行環境、重建容器映像,並重新啟動程序
有沒有替代方法? 安全公告沒有提及任何替代方法。下文的臨時措施可縮小受攻擊面,但無法涵蓋所有情況

Timeline of CVE-2026-111497: Node.js fixes on October 21, CVE published October 22, exploit traffic reported October 26, CISA KEV listing October 27, KEV due date November 10, next Node.js security release November 11

ELLIO 表示,截至 10 月 26 日,其感測器已偵測到漏洞利用流量,距離修復程式推出僅五天。被截獲的惡意載荷針對 x86-64 架構上的 Node.js 24.22.0。雖然該載荷的最後階段在 ELLIO 測試期間執行失敗,但該公司確認,同一段程式碼無須修改,便可在官方 24.22.0 版本上執行。CISA 給予美國聯邦機構截至 11 月 10 日採取行動的期限,並將勒索軟件的使用情況評為「未知」。Akamai 的遙測數據顯示,截至 10 月 26 日,仍有 61% 的網絡運行受影響版本。

Node2Shell 漏洞詳解:Brotli 缺陷如何運作?

Node2Shell 是 Node.js 執行環境內置 Brotli 解碼器中的越界寫入錯誤。損毀的壓縮資料流會令解碼器寫入超出一個 8 位元組內部緩衝區的末端,導致程序記憶體受損。這可能令應用程式崩潰、洩漏記憶體資料,或讓攻擊者在你的伺服器上執行其控制的程式碼。

根本原因是錯誤狀態分類有誤:無效的區塊切換被解讀為「需要更多輸入」,而不是「資料已損毀」,令串流解碼器繼續將位元組附加到該小型緩衝區。

問題源於 Google 的 Brotli 函式庫,影響 1.0.3 至 1.2.0 版本,因此並非只限於 Node.js。Node.js 已透過合併上游的程式碼修補 0ed4268a,修正其所用版本,並納入 24.22.1 版本及相應的同系列版本。OpenAI Codex 的兩名安全研究員 Khai Tran 和 Sylvie Meyer 通報了這個漏洞。

你的相依套件掃描工具無法偵測這項漏洞,因為解碼器直接內置於執行環境中,而非獨立套件。例如,在未修補的 Node.js 24.15.0 上執行時,npm install 命令顯示我們以 Express 5 建立的示範專案有 0 個安全漏洞。

哪些用戶面臨風險?

執行環境受感染只是面臨風險的其中一個條件,另一個條件是存在一條會將不受信任的 Brotli 資料傳送至解碼器的路徑。我們在 Node.js 24.22.1 上測試了每條路徑:傳送包含無效但無害文字(文字 not-valid-brotli)的請求本文,並附上 Content-Encoding: br 標頭;亦向每個用戶端提供有效的 Brotli 資料。

路徑 測試版本 是否會執行解碼器? 觀察到的結果
Express 5 express.json() 5.3.0 (body-parser 2.4.0) 是,預設會 400,「Decompression failed」
Express 4 express.json() 4.22.3 (body-parser 1.20.9) 否 415,不支援的編碼
Koa @koa/bodyparser 6.1.0 是,預設會 500,記錄中出現 BrotliDecoder 錯誤
Fastify 配合 @fastify/compress 9.3.0 是,註冊外掛後便會 400,FST_CP_ERR_INVALID_CONTENT
Fastify 不配合外掛 5.12.8 否 400,無效的 JSON 資料
直接使用 node:http 伺服器或 http.get 24.22.1 否 原始位元組會原樣傳遞
內置的 fetch() 函數 24.22.1 是,一定會 回應已解碼
axios、got、node-fetch 1.21.0, 16.2.0, 3.3.2 是,預設會 回應已解碼
zlib.brotliDecompress*, createBrotliDecompress 任何版本 是 這就是解碼器 API

Diagram of paths into the Brotli decoder in node:zlib: Express 5 parsers, Koa body parsers and Fastify with @fastify/compress on the inbound side, fetch, axios and got on the outbound side, while Express 4, plain Fastify and bare node:http do not reach it

有兩個結果值得仔細檢查。第一,fetch() 函數即使在請求附有 Accept-Encoding: identity 標頭時,仍會解碼 Brotli,因為它會依據回應標頭,而非你具體提出的要求。這表示應用程式呼叫的任何外部伺服器都可能讓解碼器處理資料,令 webhook 測試工具、連結預覽或 URL 匯入功能面臨風險。第二,單憑 400 錯誤回應並不能證明任何事;Express 5 和未安裝外掛的 Fastify 都會回傳 400,但只有 Express 5 實際執行了解碼器。因此,請一併檢查錯誤訊息。

你可以使用以下三條指令,檢查有哪些路徑面臨風險:

# Direct decoder use
grep -rnE "brotliDecompress|createBrotliDecompress" src/

# Parsers that decode request bodies
npm ls express body-parser @koa/bodyparser @fastify/compress

# Base images and pinned versions
grep -rnE "^FROM .*node" --include='Dockerfile*' .

請記住,只要新增一次對 fetch() 函數的呼叫,這些判斷便可能完全改變。因此,即使目前「沒有面臨風險」,也代表你必須立即套用修補程式。

如何修補 CVE-2026-111497 漏洞

請升級至所用版本分支的最新版本,而非只升級至最低修補版本。截至 11 月 5 日,以下來源均已提供修補版本:

安裝方式 所需操作
nvm nvm install 24 && nvm alias default 24
Homebrew brew upgrade node(或 node@24、node@22)
Docker FROM node:24.22.2-slim,然後執行 docker build --pull
Linux 發行版套件 請按照所用發行版的安全公告操作,因為修補程式可能會以較舊的版本號回溯套用
CI 更新 .nvmrc、engines 和 node-version,然後重新建置
無伺服器雲端環境 從已部署的函數記錄 process.version 的值以作確認;不要假設平台已自動更新

接著,處理兩個常見的疏忽:

  • 重新啟動所有項目:正在執行的程序會將舊的可執行檔保留在記憶體中,因此只升級磁碟上的檔案並不會改變任何事,必須透過 pm2、systemd 或容器管理系統等工具重新啟動程序。
  • 重新建置已部署的項目:舊的容器映像仍會保留舊的執行環境,而以不可變識別碼固定版本的映像需要進行映像安全掃描,因為版本標籤無法反映實際情況。

最後,請在已部署的容器內執行本文開頭提到的檢查,然後在 CI 執行器和開發人員的電腦上執行。若要查看每個版本分支最新的安全版本:

curl -s https://nodejs.org/dist/index.json | jq -r '[.[] | select(.security == true and (.version | test("^v(22|24|26)\\.")))] | group_by(.version | split(".")[0]) | .[] | max_by(.date) | "\(.version)  \(.date)"'

你仍在使用 20 或 25 版本嗎?目前沒有任何已修補版本可供你使用。請參閲 Node.js 20 支援終止計劃,並立即升級。

如果今天未能修補:Node.js Brotli 漏洞的緩解措施

這些步驟可以為你爭取一些時間,但沒有任何一項可以取代實際升級。

  1. 在網絡邊界拒絕 br 編碼:在代理伺服器或負載平衡器封鎖 Content-Encoding: br 標頭,並確保不區分大小寫,且能在 gzip, br 等清單中識別它。
  2. 在應用程式中拒絕編碼:在請求文字解析器之前加入這段程式碼;我們在 Express 5 上測試時,它回應了 415 狀態碼。
app.use((req, res, next) => {
  const encoding = req.headers['content-encoding'] || '';
  if (/\bbr\b/i.test(encoding)) return res.status(415).end();
  next();
});
  1. 停用自動解壓縮:設定 express.json({ inflate: false }) 後,相同請求會得到 415 狀態碼。不過,它也會拒絕以 gzip 壓縮的請求,因此請先確認用戶端是否相容。
  2. 控制傳出的回應:axios 支援 decompress: false 選項;我們測試時,位元組保持未解碼狀態。至於函式 fetch(),則沒有提供停用解壓縮的標準選項,因此必須透過允許清單和輸出流量規則,限制它可以連線的主機。
  3. 減低影響範圍:將 Node.js 服務隔離在不同環境中,並限制對當機記憶體傾印檔案的存取權限。ELLIO 指出,應用程式當機可能會令檔案中的敏感記憶體資料外洩。

密切留意 ELLIO 最先觀察到的情況:以 Brotli 編碼的請求文字突然大量湧入,以找出正在解碼這些內容的主機。因此,如果 JSON API 出現帶有 Content-Encoding: br 的異常流量,或程序當機次數突然上升,便應立即調查。

升級後確認 API 完整性:讓 AI Agent 負責處理

執行環境版本轉換可能會改變 TLS、DNS 和 HTTP 的行為,而 10 月份的更新同時涵蓋這三方面。不要手動比較差異;讓你的編碼 Agent 在升級前後執行 Apidog CLI,再提供變更報告。

npm install -g apidog-cli@latest
apidog login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com   # pick your agent when prompted

把這段提示詞交給你的編碼 Agent:

Run Apidog test suite <id> in project <id> against staging and save the
results to reports/before. After I upgrade Node.js, add a test case for
POST /orders that sends the plain text "not-valid-brotli" with
Content-Encoding: br, asserts a 4xx status, then checks GET /health
returns 200. Rerun the suite to reports/after and list every request
whose result changed.

Agent 將執行以下命令:

apidog run --test-suite <id> --project <id> -e <envId> -r cli,junit --out-dir reports/before
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <id> --file case.json
apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json
apidog run --test-suite <id> --project <id> -e <envId> -r cli,junit --out-dir reports/after

這個額外測試案例是系統完整性檢查,而不是漏洞利用攻擊;請求內容只是普通文字。在我們的測試中,受影響版本和已修補版本都因相同的填充錯誤而失敗。即使如此,這項檢查仍揭示了真實的錯誤處理漏洞:測試用的 Koa 伺服器因未處理解碼錯誤而回應 500,但任何公開 API 都應回應 4xx 類別的狀態碼。請只在預備環境執行這項測試。

執行命令參考列出所有可用選項,而 CI/CD 指南則説明如何將 JUnit 測試執行整合至自動部署流程。Apidog 免費方案最多支援 4 位用戶。

即將到來的 11 月 11 日為何重要

Node.js 專案早前預告,將於 2026 年 11 月 11 日或之後不久,為 26.x、24.x 及 22.x 版本系列推出即將發佈的安全更新,當中的最高嚴重程度評級將再次為「高」。CVE 編號尚未公開。我們的 11 月版本指南説明如何為此作好準備。

現在就修補 Brotli 漏洞,不要押後並與即將推出的更新一併處理;漏洞的詳細資訊已公開,而且目前已有活躍的漏洞利用活動。你今星期進行的升級,也是為下一次升級作實戰演練:同樣的資產清點、同樣的映像檔重建、同樣的測試套件。過往的 PHP2Shell 和 React2Shell 等漏洞,也完全遵循同一模式。

常見問題 (FAQ)

CVE-2026-111497 目前是否正遭利用? 是。CISA 於 2026 年 10 月 27 日將其加入已知遭利用漏洞目錄,列於 Google Brotli 項目下;ELLIO 則在 10 月 26 日前已記錄到活躍的利用嘗試。

它的評級是高危還是嚴重? 兩種評級都正確且符合實際情況:Node.js 將其評為高危,NVD 資料庫則根據 CVSS 3.1 將其評為嚴重,評分為 9.8;Google 根據 CVSS 4.0 給予 9.2 分。制定計劃時,應以漏洞已遭利用這一事實為準。

我使用 Express 4,是否安全? 傳入的請求內容不會在你的應用程式中傳到解碼器,但對 fetch() 和 axios 的呼叫,以及直接使用程式庫 node:zlib,仍會傳到解碼器。此外,同一版本亦修正了另外九個 CVE 漏洞,因此無論如何都應升級。

Node.js 20 版本是否受影響? Node.js 專案不會評估已結束支援的版本系列,也不會為其提供修補程式。請將 20.x 和 25.x 視為未修補且未經評估的版本,並盡快升級至受支援的版本。

除了 Node.js,其他系統也會受此漏洞影響嗎? 會。GitHub 上的安全公告涵蓋 PyPI 上的套件 brotli 和 brotlicffi;開發人員亦宣佈已為 Bun 1.4.4 和 .NET 推出修正。請分別更新每個解碼器,因為升級 Node.js 只會更新其內置的版本。

來源:DEV Community · dev.to