跳到正文
Calif:Research(AI 漏洞研究)·· 1 天前精選AI 評分85

Codex 發現利用 HTTP/2 標頭壓縮耗盡伺服器資源的 HTTP/2 Bomb

Codex Discovered a Hidden HTTP/2 Bomb

AI 導讀

Calif Research 公開由 Codex 發現的 HTTP/2 Bomb,這是一種結合 HPACK 標頭壓縮與 HTTP/2 流量控制、可耗盡伺服器記憶體的遠端阻斷服務攻擊。

推薦理由

文章拆解 HPACK 標頭壓縮如何放大伺服器記憶體分配,以及 HTTP/2 流量控制如何令這些記憶體持續被佔用,並整理不同伺服器的緩解方式。

正文 · 繁體中文

14年前,我曾協助攻破 HTTP 標頭壓縮,之後受邀審查修補方案,而該方案後來成為 HTTP/2 的一部分。如今一切兜了一圈:我們今天公開一種我當年錯過的攻擊。

我們現正公開 HTTP/2 Bomb,這是一種針對大部分主流網頁伺服器的遠端拒絕服務攻擊,包括:

  • nginx
  • Apache httpd
  • Microsoft IIS
  • Envoy
  • Cloudflare Pingora

上述每種伺服器的預設 HTTP/2 設定都存在這種漏洞行為。

Codex 發現了這種攻擊,並結合了兩種人類已知十年的技術:壓縮炸彈和 Slowloris 式佔用攻擊。壓縮炸彈針對 HPACK(HTTP/2 的標頭壓縮方案):傳輸中的一個字節會令伺服器配置一份完整標頭,每個請求重複數千次。佔用攻擊則利用零字節流量控制視窗,令伺服器永遠無法釋放已配置的記憶體。

一次出於好奇的 Shodan 搜尋發現,有超過 880,000 個網站支援 HTTP/2,並使用上述其中一種伺服器;不過,很多網站位於 CDN 後方,要令它們無法運作困難得多。

一部透過 100Mbps 連線的家用電腦,可在數秒內令有漏洞的伺服器無法存取。針對 Apache httpd 和 Envoy,單一用戶端約 20 秒便可佔用並鎖定伺服器 32GB 記憶體。

HTTP/2 Bomb against Apache httpd, Envoy, IIS, and nginx 由左上角起順時針方向:Apache httpd、Envoy、nginx、Microsoft IIS。(2 倍速播放)

伺服器放大倍數示範結果
Envoy 1.37.2~5,700:1約 10 秒內佔用約 32 GB
Apache httpd 2.4.67~4,000:1約 18 秒內佔用約 32 GB
nginx 1.29.7~70:1約 45 秒內佔用約 32 GB
Microsoft IIS(Windows Server 2025)~68:1約 45 秒內佔用 64 GB

鳴謝

  • 感謝 Quang Luong 發現這種攻擊。他將於 6 月在 Stanford 舉行的 Real World AI Security conference 上介紹相關技術。
  • 感謝 Jun Rong 和 Duc Phan 確認這種攻擊也適用於其他網頁伺服器。

技術詳情

HPACK(RFC 7541)是一種有狀態的壓縮方案。HTTP/2 連線的兩端各自維護一個動態表格,記錄最近出現的標頭。發送端可將標頭插入表格一次,之後在後續請求中透過索引引用,通常只需一個字節。接收端查找索引,並將完整標頭的新副本放入正在組裝的請求中。

HTTP/2 本身(RFC 9113)加入每個串流的流量控制:接收端會公佈一個視窗,發送端在收到 WINDOW_UPDATE 之前,不能傳送超出該視窗限制的 DATA。尤其重要的是,用戶端可控制伺服器回應所使用的視窗。

上述每項功能都有已知的濫用方式,而這種攻擊將它們串連起來:

  • HPACK 索引引用炸彈:先在動態表格中放入一個標頭,然後發出數千個 1 字節的索引引用。攻擊者每次引用只需傳送 1 個字節,伺服器卻要配置約 70 字節(nginx、IIS、Pingora)至約 4,000 字節(Apache httpd、Envoy)的記憶體。
  • HTTP/2 視窗停滯:公佈一個零字節流量控制視窗,令伺服器永遠無法完成傳送回應,然後間歇傳送 1 字節的 WINDOW_UPDATE frame,持續重設傳送逾時時間,令每項記憶體配置一直被佔用,直至伺服器逾時時間所容許的最長時間。

這些做法都不是全新。Cory Benfield 在 2016 年透過 CVE-2016-6581 創造了「HPACK Bomb」一詞;2025 年,Gal Bar Nahum 對 Apache httpd 達到約 4000 倍放大效果,編號為 CVE-2025-53020(修補説明)。不涉及壓縮放大器的 HTTP/2 Slowloris 類型資源耗盡問題,同樣可追溯至那段時期:Apache httpd 的無限制 CONTINUATION frame 漏洞 CVE-2016-8740,以及工作執行緒耗盡漏洞 CVE-2016-1546。

這裏的新意在於放大效應來自哪裏。傳統的炸彈攻擊會把一個大型值塞入表格,然後反覆引用,因此伺服器開始限制解碼後標頭的總大小。我們的變體剛好相反:標頭幾乎是空的,放大效應來自伺服器為每個項目配置的管理資料。由於幾乎沒有內容需要解碼,解碼後大小的限制根本不會觸發。

對於改為限制標頭欄位數量的伺服器(Apache、Envoy),Cookie 就是繞過限制的方法:RFC 9113 §8.2.3 明確允許將 Cookie 標頭拆分成每個片段各佔一個欄位,而這些伺服器沒有把 Cookie 片段計入限制。接下來的放大效應取決於伺服器如何重新組合 Cookie。Envoy 會把每個片段附加到緩衝區,因此,一個 4 KB 的大型 Cookie 值被引用 32k 次,邏輯比率便約為 3,600:1(最終 Cookie 位元組數除以線路傳輸位元組數);實測 RSS 比率更高:跨串流約為 3,800:1,而在單一串流中,若再計入累積的配置器開銷,最高可達約 5,700:1。Apache httpd 每收到一個片段都會重新建立整個合併字串,並讓每個較舊的副本一直保留到串流清理為止,因此即使 Cookie 是空的,比率也約為 4,000:1。

在實際攻擊中,你大概不會想讓程序真的因 OOM 而終止,因為被終止的工作程序只會重新啟動,回復正常狀態。更有效的做法是把記憶體壓力維持在終止門檻以下,迫使機器使用 swap,令同一部機器上的其他所有請求都變得極慢。

概念驗證

按伺服器分類的 AI 生成文章、Docker 實驗環境及 PoC 腳本可在此找到。

請勿將這些內容用於你不擁有的基礎設施。

漏洞披露

我們在 4 月向 nginx 披露了問題。他們的回應是從 freenginx引入 max_headers 指令,並於翌日將其加入 1.29.8。現階段,我們認為這項攻擊已公開。

我們在 May 27 向 Apache 披露問題,Stefan Eissing 當天便修正了問題,方法是讓 cookie 標頭計入 LimitRequestFields。該問題獲分配 CVE-2026-49975。

上述修正提交已公開,並直接披露了攻擊向量;任何能力足夠的 AI 模型都能將這些差異轉化為可用的漏洞利用程式,而我們正是透過這種方式發現 Microsoft IIS、Envoy 和 Pingora 也容易受到攻擊。我們已通知它們的維護者。鑑於從修正提交到製作出漏洞利用程式的路徑如今已非常短,我們現公開這篇文章,讓用戶參考以下緩解措施。

緩解措施

nginx:升級至 1.29.8+,此版本新增 max_headers 指令,預設值為 1000。如果無法升級,請使用 http2 off; 停用 HTTP/2。

Apache httpd:修正已加入 mod_http2 v2.0.41,可從獨立的 mod_http2 版本取得,亦已加入 httpd trunk,但尚未納入任何 2.4.x 版本。如果無法升級,請設定 Protocols http/1.1 以停用 HTTP/2。調低 LimitRequestFieldSize 可縮小每條串流的影響範圍(它會限制合併後 Cookie 的大小,從而限制片段數量),但這只能部分緩解問題,因為攻擊者仍可透過多條串流和連線放大效果。調低 LimitRequestFields 在此毫無作用:重複的 Cookie 片段不會計入該限制。

Microsoft IIS、Envoy、Cloudflare Pingora:撰寫本文時尚無可用修補程式。如可行,請停用 HTTP/2;否則,請在伺服器前端部署可強制限制每個請求標頭數量的機制。

一般而言:「最大解碼標頭大小」和「最大標頭數量」是兩種不同的限制,伺服器兩者都需要。任何 HTTP/2 終止點都應限制每個請求的標頭欄位數量,包括 cookie 個零碎欄位,並且不論 WINDOW_UPDATE 活動情況如何,都應限制停滯串流的存續時間。如果目前無法做到上述任何一點:就嚴格限制每個工作程序的記憶體(cgroups、ulimit -v、容器限制),確保遭攻擊的工作程序會在拖累整部機器使用 95% 資源前因 OOM 被終止並重新啟動。工作程序很少需要數 GB 記憶體;讓核心及早終止其中一個,比任由攻擊者把整部機器的資源使用率維持在 95% 更理想。

重點

RFC 7541 有一整節討論這種威脅。§7.3 記憶體消耗開首指出:「攻擊者可以嘗試令端點耗盡記憶體」,接着解釋 HPACK 會透過 SETTINGS_HEADER_TABLE_SIZE 限制動態表,然後便認為問題已處理妥當。但五個互不相關的實作都讀過該節,卻仍然推出同一類錯誤,缺陷就在規格本身。

更深層的疏漏,是規格純粹以放大比率來描述記憶體風險,但比率只説明瞭問題的一半。如果請求完成時便會釋放記憶體,70:1 的放大器並無危害。但 HTTP/2 讓用戶端幾乎不費成本便能保持連線開啟,令每個已配置的位元組都持續被佔用,時間長短由用戶端任意決定,這便成為攻擊手段。

另一點值得留意的是這項漏洞的發現方式。攻擊的兩個部分都已公開十年。Codex 所做的,是閲讀程式碼庫,發現兩者可以組合起來,並構建出這種組合式攻擊。一旦看出來,這種組合就顯而易見;然而據我們所知,之前沒有人曾把它組合起來攻擊這些伺服器。

後記

團隊向我介紹這項研究時,我不禁想起 2012 年。那一年,Juliano Rizzo 和我發現了 CRIME,這是一種壓縮預言機攻擊,可從經過壓縮的 HTTP 標頭還原 Cookie。當時我在 Google 工作,因此受邀審閲修補方案,而這項方案後來成為 HPACK。我剛重新讀過當時的審閲筆記:我從未考慮過這種攻擊。我當時過度專注於對付 CRIME,結果漏看了這枚炸彈。

程式碼及 PoC →

來源:Calif:Research(AI 漏洞研究) · calif.io