Boost 1.92 收緊 Beast HTTP 解析,拒絕 CL 加 TE 請求
Boost 官方 release notes · Boost 1.92.0
Boost.Beast 的 http::basic_parser 以前對 Content-Length 與 Transfer-Encoding 並存的請求比較寬鬆,1.92.0 起不論欄位順序一律拒絕。這是 Boost 1.92.0 的 Beast 與 URL 一系列硬化修正中最值得先看的一項。
同一版還修了 URL 的 heap buffer overflow,也讓 Heap 與 Lockfree 宣告最後一個支援 C++14 的版本。
原本的問題
HTTP/1.1 用 Content-Length 或 Transfer-Encoding: chunked 決定訊息在哪裡結束。當兩者同時出現、或 Transfer-Encoding 的最後一個編碼不是 chunked,前端代理與後端如果各自挑不同的欄位,就會對「下一個請求從哪開始」得出不同答案,這是 request smuggling 的典型入口。
release notes 沒有說明 1.92.0 之前 Beast 在這些情況下的具體行為,所以本文只依 notes 列出「現在會拒絕什麼」,不推測舊版怎麼處理。
核心改動
依 Beast 一節,http::basic_parser 新增或收緊的檢查包括:
- 拒絕
Content-Length與Transfer-Encoding並存,與欄位出現順序無關。 - 拒絕
Transfer-Encoding最後一個編碼不是 chunked 的請求。 - 拒絕 HTTP/1.0 請求使用 chunked transfer-encoding。
- 驗證 chunk extension 內的 quoted-string。
- trailer 中的 framing 與 connection 控制欄位會被忽略(
http::parser則直接丟棄)。
另外 http::message::prepare_payload 會拒絕帶 body 的 1xx 回應,websocket::stream 會拒絕最高位元為 1 的 64 位元 frame 長度,並接受 close code 1014。
| 輸入 | 1.92.0 的處理 |
|---|---|
Content-Length + Transfer-Encoding | 拒絕(不看順序) |
Transfer-Encoding: gzip(未以 chunked 結尾) | 拒絕 |
| HTTP/1.0 請求 + chunked | 拒絕 |
| trailer 內的 framing 欄位 | 忽略或丟棄 |
URL 函式庫的記憶體錯誤
Boost.URL 修了 normalize_path 的 heap buffer overflow:觸發條件是沒有 authority、且正規化後的路徑以 // 開頭的 URL(PR#995)。此外還修了 ipv6_address_rule 的未初始化讀取與 unsigned overflow 的 sanitizer 發現(PR#994),以及 url_base::edit_params 對 decoded query 大小的追蹤錯誤(PR#990)。release notes 未提供 CVE 編號。
影響範圍
直接用 Beast 寫 HTTP server 或反向代理的人:升級後,原本被放行的 CL+TE 請求會被解析器拒絕。如果內部有奇怪的 client 或測試工具會同時送兩個欄位,要檢查它們現在收到的錯誤。反過來說,若你的代理在 Beast 前面,它與 Beast 對這類請求的判斷終於一致。
處理不受信任 URL 的服務(爬蟲、轉址檢查、路徑正規化):normalize_path 的 overflow 只需要特定形狀的輸入,建議升級,或先檢查是否會對外部輸入呼叫它。
Heap 與 Lockfree 的使用者:兩者的 notes 都寫「This release is the last to support C++14. Future releases will require C++17.」,仍停在 C++14 的專案要規劃升級編譯標準,或固定在 1.92.x。
MSM 的 backmp11 後端使用者:notes 標示事件佇列與 active state policy 有 breaking change(#178、#222),升級前先讀該節。
同版其他值得一提的項目
boost::lockfree::mpsc_weak_queue(多生產者單消費者)與boost::lockfree::bounded_ticket_queue(ring buffer 的有界 MPMC queue)。- 新容器
boost::container::hub,由 Joaquín M. López Muñoz 設計。 - Charconv 的整數
to_chars/from_chars支援 CUDA,Decimal 初步支援decimal32_t、decimal64_t、decimal128_t的 CUDA。 - Windows 的
.dll預設裝到 binary 目錄,並新增--dlldir選項;CMake 設定檔支援以find_package元件請求 header-only 函式庫。