2026 年 7 月 15 日,nginx 發布 1.30.4(stable)與 1.31.3(mainline),修掉了一個 CVSS 9.2 的堆積緩衝區溢位 CVE-2026-42533。攻擊者不需要任何認證,只要構造特定 HTTP 請求即可觸發;預設組態下的後果是 worker 行程崩潰重啟(阻斷服務),在 ASLR 被關閉或可繞過的環境裡則有升級為遠端程式碼執行的可能。
觸發條件:map + 正規表示式 + 擷取群組
根因不在 HTTP 剖析器,而在 nginx 的兩趟指令稿求值機制:計算長度的那一趟與真正寫入值的那一趟共用同一份 PCRE 擷取狀態。當一條帶正規表示式的 map 指令剛好在兩次引用同一個擷取群組(例如 $1)之間被求值時,擷取狀態被悄悄覆寫,兩趟對緩衝區大小的判斷隨之不一致,於是寫入越界。
換句話說,不是每台 nginx 都會被打中,但受影響的版本區間寬得離譜:0.9.6 一直到 1.30.3(stable)/1.31.2(mainline),也就是 2011 年以來的絕大多數版本。商業版方面 NGINX Plus R33–R36 受影響(修復於 R36 P7),37.0.0.1–37.0.2.1 修復於 37.0.3.1。
為什麼現在必須動手
發現者在修補程式發布後刻意壓了 21 天才公開完整利用細節與 PoC,給管理員留升級視窗——這個視窗早已過去。同一年的另一個例子更能說明速度:2026 年 5 月修復的 CVE-2026-42945(ngx_http_rewrite_module 堆積溢位,被稱作「Nginx Rift」),修補程式發布約一週內就出現了實際攻擊;當時估計公網上約有 570 萬台 nginx 跑著可能受影響的版本。半年內兩個同類問題,說明「裝完就不再動」的 Web 伺服器是真實風險。
三步自我檢查
- 查版本,但別只信
nginx -v:Debian/Ubuntu 的發行版套件會把安全修補回溯移植(backport)到舊版本號上,版本號停在 1.24.0 不代表沒修。用發行版套件的看apt policy nginx的套件版本尾號,並用apt changelog nginx確認是否提到該 CVE;用官方來源或自行編譯的,才直接和 1.30.4 / 1.31.3 比對。 - 查組態裡有沒有帶正規表示式的
map:grep -rn "map " /etc/nginx/,重點看比對項目裡以~開頭的正規表示式,以及同一條請求路徑上多次引用$1這類擷取群組的寫法。沒有這種組合,風險面會小很多。 - 查記錄檔裡 worker 是不是在無聲重啟:
grep -i "worker process.*exited on signal" /var/log/nginx/error.log。反覆出現 signal 11 是典型症狀,而在使用者那一側它只表現為「偶發 502」,非常容易被當成網路抖動放過去。
升級動作
發行版套件:sudo apt update && sudo apt install --only-upgrade nginx,然後 sudo nginx -t && sudo systemctl reload nginx。官方來源或自行編譯:升到 1.30.4 / 1.31.3 以上,nginx -t 通過再 reload。reload 不會中斷既有連線,不必挑維護視窗。順帶一提,這兩個版本還一起修掉了 CVE-2026-60005(ngx_http_slice_module 記憶體外洩)與 CVE-2026-56434(ngx_http_ssi_module 釋放後使用),升一次解決三個。
把「能自己修補」當成選型條件
應對這類公告的速度,取決於你有沒有 root、能不能自己決定何時 reload。共享主機上只能等服務商排程,而且通常看不到完整的 error.log;在自己的 VPS 上,從看到公告到 reload 完成十分鐘足夠。SharkCloud 的日本、新加坡、香港、美國節點都是獨立執行個體,系統與 Web 服務版本完全由你掌控,安全公告出來當天就能處理完,而不是排進下一個維護視窗。