Codex 發現利用 HTTP/2 標頭壓縮耗盡伺服器資源的 HTTP/2 Bomb
Codex Discovered a Hidden HTTP/2 Bomb
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 記憶體。
由左上角起順時針方向: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_UPDATEframe,持續重設傳送逾時時間,令每項記憶體配置一直被佔用,直至伺服器逾時時間所容許的最長時間。
這些做法都不是全新。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,結果漏看了這枚炸彈。
來源:Calif:Research(AI 漏洞研究) · calif.io