← 回文章列表

CVE-2026-54571:ESPAsyncWebServer 整數溢位漏洞,一個請求就能讓 ESP32 當機重開

前言

只要做過 ESP32 或 ESP8266 專案的人,對 ESPAsyncWebServer 應該都不陌生。從智慧插座的設定頁、感測器儀表板,到 OTA 韌體更新介面,大量的 IoT 裝置都靠它在晶片上跑出一個非同步的 HTTP/WebSocket 伺服器。

2026 年 9 月 17 日,GitHub 作為 CNA 公布了 CVE-2026-54571(對應 GitHub Security Advisory GHSA-4phx-fcj6-46r4):ESPAsyncWebServer 在處理 multipart/form-data 請求時,存在一個**整數溢位(Integer Overflow)**問題,遠端攻擊者不需要任何帳號密碼,就能讓裝置卡死並被看門狗強制重開,形成阻斷服務(Denial of Service, DoS)。

這個漏洞的成因非常「經典」,也很值得所有寫嵌入式程式的開發者拿來當作借鏡。

漏洞重點整理

項目 內容
CVE 編號 CVE-2026-54571
受影響產品 ESP32Async / ESPAsyncWebServer
受影響版本 3.11.1 之前的所有版本
修補版本 3.11.1
弱點類型 CWE-190:Integer Overflow or Wraparound
CVSS v4.0 8.7(High)
攻擊向量 AV:N/AC:L/AT:N/PR:N/UI:N(網路、低複雜度、免權限、免使用者互動)
影響面 可用性(Availability)高;機密性與完整性無影響
支援平台 ESP32、ESP8266、RP2040、RP2350

問題出在哪裡?

HTTP 的 multipart/form-data 格式,會用一段由客戶端自訂的 boundary 字串來分隔每個欄位或上傳檔案。伺服器端的解析器必須逐位元組比對輸入資料,判斷目前是否讀到了 boundary。

在 ESPAsyncWebServer 的 src/WebRequest.cpp 中,負責逐位元組解析的 _parseMultipartPostByte 會用一個變數 _boundaryPosition 記錄「目前比對到 boundary 的第幾個字元」。問題在於,這個變數是以 8-bit 型別儲存,最大只能表示 255。

當攻擊者送出一個 boundary 長度剛好是 256 bytes 的請求時,計數器從 255 再加 1,就會繞回 0(wraparound)。解析迴圈因此永遠等不到「比對完成」的條件,陷入無法終止的狀態,持續吃滿 CPU。

為什麼會導致裝置重開?

ESP32 與 ESP8266 上運行的 FreeRTOS 有**看門狗計時器(Watchdog Timer)**機制:當某個任務長時間霸佔 CPU、沒有讓出執行權,系統會判定為異常並強制重啟晶片。

換句話說,攻擊流程很單純:攻擊者只要能連到裝置的 HTTP 服務,送出一個精心設計的 multipart 請求,裝置就會卡住、被看門狗重開。若攻擊者反覆發送,裝置就會陷入不斷重啟的循環,實際上等於完全無法提供服務。

風險評估

美國 CISA 的 ADP(Vulnrichment)在 SSVC 評估中標註:

  • Exploitation:none——截至評估時,尚未觀察到實際的在野利用。
  • Automatable:yes——攻擊可以被自動化、大規模執行。
  • Technical Impact:partial——影響限於可用性,並不會讓攻擊者取得控制權或竊取資料。

雖然這個漏洞不會造成遠端程式碼執行,但對 IoT 場景來說,「可用性」往往就是一切。想像一下工廠的感測節點、門禁控制器或農業灌溉系統被人一鍵打掛反覆重開,造成的營運衝擊可能遠比資料外洩更直接。再加上許多裝置的 Web 介面被直接暴露在區網甚至公網上,可自動化的特性讓大範圍掃描攻擊的門檻很低。

修補與因應建議

官方已在 v3.11.1 版本中修正此問題(相關修補見 PR #445 與 commit b928de7)。建議開發者與維運人員依下列步驟處理:

  1. 升級函式庫:
    • PlatformIO 使用者:在 platformio.ini 的 lib_deps 中將 ESP32Async/ESPAsyncWebServer 指定為 ^3.11.1 以上,然後重新編譯。
    • Arduino IDE 使用者:透過程式庫管理員更新至 3.11.1 以上。
  2. 重新編譯並部署韌體:函式庫是編譯進韌體的,光更新開發環境不夠,必須把新韌體推到每一台現場裝置(OTA 或實體燒錄)。
  3. 盤點受影響裝置:特別留意使用舊版 fork(例如早期 me-no-dev/ESPAsyncWebServer 衍生版本)的專案,確認其程式碼是否含有相同的解析邏輯。
  4. 縮小攻擊面:
    • 不要把裝置的 Web 管理介面直接暴露在網際網路上。
    • 以 VLAN、防火牆或反向代理隔離 IoT 裝置,必要時在閘道端限制請求標頭長度。
    • 若應用根本不需要檔案上傳或表單 multipart 功能,可評估是否關閉相關路由。

給嵌入式開發者的啟示

這個漏洞再次提醒我們:在資源受限的 MCU 上,為了節省記憶體而選用 uint8_t 這類小型別是常見做法,但只要這個值會受到外部輸入影響,就必須明確檢查上下界。

幾個實務上的建議:

  • 長度欄位與索引一律做邊界檢查:例如 boundary 依 RFC 2046 的規範最長應為 70 個字元,超出就直接拒絕,而不是硬著頭皮解析。
  • 選用足夠寬的型別:計數器、索引若可能超過 255,就用 size_t 或 uint16_t,多佔的那一兩個 byte 換來的是穩定性。
  • 加入 fuzz testing:對 HTTP 解析器這類處理不可信輸入的模組,用極端長度、邊界值(255、256、65535、65536)做測試,往往能提早抓出這類 off-by-one 與 wraparound 問題。
  • 避免長時間不讓出 CPU 的迴圈:在 FreeRTOS 環境中,解析迴圈應設有最大迭代次數或逾時保護,即使邏輯出錯也不至於拖垮整個系統。

結語

CVE-2026-54571 不是那種會登上大新聞的遠端接管漏洞,但它影響的是一個在 Maker 社群與商用 IoT 產品中都極為普及的函式庫,而且攻擊門檻低、可自動化。如果你的產品或專案用到了 ESPAsyncWebServer,請把升級到 3.11.1 排進這週的待辦清單,並趁這個機會檢視一下自家韌體的 OTA 更新機制是否完善——畢竟,能不能快速把修補推到現場,才是 IoT 資安真正的考驗。


參考資料