題幹與適用場景
一個應用經過 CDN、反向代理、WAF 與後端服務。安全團隊發現不同元件對同一 HTTP/1.1 位元組流的請求邊界解釋不一致,攻擊者可能讓前端以為只有一個請求,後端卻從剩餘位元組解析出第二個請求。請解釋請求走私原理,說明 Content-Length 與 Transfer-Encoding 衝突時的安全處理,並給出偵測、修復、驗證與上線方案。
RFC 9112 指出,多個接收方使用不同健壯性解析規則會產生請求走私風險;OWASP 將其歸因於前端與後端元件的請求解析不一致。題目考察候選人能否把抽象的「解析差異」還原為位元組流、連線重用與安全邊界問題,而不是只背某個攻擊縮寫。
面試官考察點
- 能否區分訊息分幀、路由與應用層參數驗證三個層次。
- 能否準確說明
Content-Length、Transfer-Encoding與 HTTP/1.0 降級邊界。 - 能否指出代理鏈中誰解析、誰重用連線,以及殘留位元組如何影響下一請求。
- 能否提出拒絕歧義請求、統一解析器與關閉連線等防禦組合。
- 能否設計不發送真實副作用的測試、監控與灰度回滾。
- 能否說明 HTTP/2 或 HTTP/3 仍需檢查翻譯層,不能宣稱升級協定就解決。
回答前需要釐清的問題
- 鏈路中有哪些 HTTP 版本與中介軟體?預設至少有 HTTP/1.1 代理與後端連線池。
- 前後端是否重用同一 TCP 連線?請求走私通常依賴連線重用或解析狀態不同。
- 是否允許分塊傳輸與請求本文?預設公共入口允許,但可選擇統一拒絕歧義組合。
- 修復目標是立即止血還是長期消除解析差異?分別給出臨時與永久措施。
- 測試環境能否使用隔離後端與無副作用端點?預設必須使用隔離端點,不能在生產發送破壞性載荷。
30 秒回答框架
我會先畫出代理到後端的位元組流與連線重用關係。請求走私的根因是不同接收方用不同規則決定訊息長度,尤其同時出現 Content-Length 與 Transfer-Encoding 或非法重複長度時。入口應拒絕歧義請求,嚴格按 RFC 解析,異常後關閉連線,代理與後端使用相同實作與版本。修復後用隔離端點與雙元件對照測試確認邊界一致,監控異常 400、連線重置與解析錯誤,灰度期間保留舊路由以便回滾。
分步驟深入解答
第一步:畫出訊息與連線邊界
先列出客戶端、CDN、WAF、反向代理與後端各自是否解析請求、是否重寫標頭、是否重用上游連線。解釋 HTTP/1.1 是位元組流協定,接收方必須從標頭欄位推導本文長度;兩層對邊界結論不同時,剩餘位元組可能被下一層當成另一請求。
不要從攻擊載荷開始背誦。先用無副作用示意位元組流說明「前端讀到一個請求,後端讀到兩個請求」的狀態變化,才能證明理解邊界。
第二步:說明長度規則與歧義
RFC 9112 對本文長度、Content-Length 與 Transfer-Encoding 給出明確規則。請求同時帶有二者時,接收方不能各自選一個繼續處理;應視為潛在攻擊並拒絕,必要時關閉連線。重複且值不同的 Content-Length 同樣必須拒絕,不能取第一項或最後一項。
收到含有 Transfer-Encoding 的 HTTP/1.0 請求時,伺服器不能把它當正常分塊語意;應按規範處理錯誤並關閉連線。關鍵是所有接收方採用相同嚴格規則,而不是依賴「更寬容」相容壞客戶端。
第三步:解釋連線重用如何放大影響
前端代理可能把一條客戶端連線拆成多個上游請求,後端連線池則在回應完成前繼續等待剩餘位元組。前後端邊界不同時,攻擊者注入的前綴會留在重用連線中,成為下一請求開頭。受影響對象可能包括快取、認證路由、內部管理端點與其他租戶請求。
因此修復不能只改應用路由。要檢查代理是否在解析錯誤後重用連線、是否清空緩衝、是否把異常請求轉發到不同後端,以及 HTTP/2 到 HTTP/1.1 翻譯層是否重新產生一致長度欄位。
第四步:給出入口止血策略
邊緣層先拒絕同時出現 Content-Length 與 Transfer-Encoding 的請求、重複長度欄位、非法分塊語法與不支援版本。解析失敗後關閉連線,不把剩餘位元組交給下一請求。臨時措施可對受影響路由停用上游連線重用,但會增加延遲與連線成本,只能止血。
拒絕規則要有明確例外與日誌分類,避免元件各自實作黑名單。能統一升級解析庫時,應讓代理與後端共享嚴格規範行為,並用相容性清單處理真實客戶端。
第五步:統一解析與標頭規範化
入口應在單一解析邊界完成訊息分幀,再把結構化請求交給應用。禁止應用重新解析原始標頭或信任代理傳來的「已驗證長度」。代理必須重寫請求時,刪除歧義欄位並依實際轉發本文重新產生規範長度,下游不能看到舊欄位。
HTTP/2 或 HTTP/3 的幀層不同,但到 HTTP/1.1 的閘道仍可能產生解析差異。檢查每個協定翻譯點的標頭合併、本文緩衝、異常連線處理與是否允許降級。
第六步:設計安全測試
在隔離環境準備前端代理與後端回顯服務,測試只記錄請求 ID、解析長度與抵達順序。覆蓋衝突長度、重複長度、非法分塊、HTTP/1.0 降級、連線重用、逾時與代理重試。測試斷言前後端看到相同請求數、方法、路徑與本文長度。
不要把會修改帳戶、訂單或快取的載荷送到生產。可用影子流量、合成連線與唯讀端點;若必須驗證真實鏈路,先關閉副作用並保留連線級日誌。
第七步:監控、灰度與回滾
監控解析錯誤、異常 400/431、連線重置、上游逾時、同一連線多請求邊界異常,以及 WAF 與後端請求數不一致。按代理版本、協定、租戶與路徑分層,避免平均值掩蓋單一邊緣節點。
先讓新解析策略在影子或小比例流量運行,設定停止條件,例如解析錯誤激增、合法客戶端失敗率上升或連線資源耗盡。回滾恢復舊路由與設定版本,保留「拒絕歧義請求」的安全開關,不能為恢復相容而重新打開寬鬆解析。
第八步:複雜度與溝通
單次訊息分幀在讀取標頭與本文時是線性於訊息大小;防禦重點不是微優化,而是每個位元組只被一個規範解析邊界消費。把規範、元件版本、連線策略與測試矩陣寫進操作手冊。
向非安全團隊解釋時,用「兩個收件人對同一信封頁數理解不同」說明風險,再給出可驗證工程動作:拒絕歧義、統一解析、錯誤斷線、隔離測試與可回滾灰度。
高品質示範回答
請求走私不是單個應用路由的 bug,而是代理鏈對同一 HTTP/1.1 位元組流產生不同訊息邊界。前端可能依 Content-Length 讀完請求,後端卻依 Transfer-Encoding 繼續讀分塊本文;攻擊者留下的位元組可能成為重用連線的下一請求。我會盤點每個解析與翻譯點,統一升級嚴格遵循 RFC 9112 的實作,入口拒絕二者並存、重複長度與非法分塊,解析錯誤後關閉連線。
我會用隔離回顯後端測試衝突長度、連線重用、重試與協定翻譯,斷言各層看到的請求數、路徑與本文長度一致。上線先影子運行再灰度,監控解析錯誤、連線重置、合法請求失敗率與前後端計數差異。超過停止條件就回滾路由與版本,但保留拒絕歧義請求,避免用寬鬆解析換回表面相容。
常見錯誤
- 只背兩個攻擊縮寫,不解釋位元組流與連線重用。
- 說「優先 Content-Length」或「優先 Transfer-Encoding」,卻忽略歧義請求應拒絕。
- 重複
Content-Length時取第一項或最後一項繼續處理。 - 只修改後端應用,忽略 CDN、WAF、代理與協定翻譯層。
- 測試直接打生產副作用端點,或沒有斷言前後端請求數一致。
- 解析錯誤後繼續重用連線,讓殘留位元組污染下一請求。
- 認為 HTTP/2 或 HTTP/3 自動消除閘道翻譯風險。
- 灰度只看總體 5xx,不分元件版本、協定與合法客戶端失敗率。
追問及應對
同時出現 Content-Length 與 Transfer-Encoding 時怎麼做?
按嚴格規範視為歧義請求並拒絕,通常在解析邊界關閉連線。所有代理與後端都要採用同一規則,不能讓一層選一個繼續轉發。
重複的 Content-Length 值相同也要拒絕嗎?
跨元件鏈路中最安全是拒絕重複欄位,除非整條鏈路明確採用相同規範合併規則。相容需求應用受控白名單與測試解決,不能讓元件自行決定。
如何驗證修復沒有破壞正常客戶端?
收集合法客戶端的協定版本、本文編碼與代理路徑,在隔離環境做回放與合成測試。灰度監控合法 4xx、連線重置與延遲,按客戶端類型準備回滾或升級。
HTTP/2 是否完全免疫請求走私?
HTTP/2 二進位幀減少部分 HTTP/1.1 分幀歧義,但 HTTP/2 到 HTTP/1.1 閘道仍會產生標頭與本文。必須稽核翻譯規則、連線重用與下游解析,不能只看客戶端協定。
代理解析失敗後為什麼應關閉連線?
解析失敗時無法證明緩衝剩餘位元組屬於目前或下一請求。關閉連線丟棄不確定狀態,可阻止殘留位元組在重用連線中被重新解釋;代價是重建連線,需監控資源影響。
如何區分請求走私與快取投毒?
請求走私是訊息邊界解析差異,快取投毒是讓快取存入攻擊者控制的回應或鍵。走私可能是投毒前置條件,但修復應先統一解析與斷線,再獨立驗證快取鍵、回應路由與權限。
會保留哪些稽核欄位?
記錄代理與後端版本、協定、連線 ID、解析結果、拒絕原因、標頭規範化摘要、請求 ID 與回應狀態。不記錄敏感本文;欄位要能關聯各層邊界判斷與最終處置。