curl 收緊 CONNECT 處理:401 不是代理驗證挑戰
curl 專案在 2026 年 9 月 4 日合併一項聚焦 HTTP 代理的修正:當代理對 CONNECT 請求回傳 401 Unauthorized 時,curl 應忽略該隧道交換中的 WWW-Authenticate 並讓連線失敗。代理驗證仍應由 407 Proxy Authentication Required 與 Proxy-Authenticate 驅動。

這項區別很重要,因為 CONNECT 請求送往代理,而不是目標來源站。401 屬於來源站驗證語義,407 才屬於代理驗證。若用戶端在建立隧道時回應 401,可能混淆信任邊界並觸發不應發生的驗證重試。
截至 9 月 9 日,修正已合併至 curl 開發分支,並列入下一維護版本的開發發布說明;這不代表所有已安裝的 curl 套件都已包含修正。調整正式環境策略前,必須核對實際二進位版本與發行商是否回移補丁。
公開來源說明: curl 專案 PR 22817《HTTP-CONNECT: do not react to 401 responses》,2026 年 9 月 3 日提交、9 月 4 日合併;curl 專案開發版發布說明,2026 年 9 月 9 日查閱。
發生了什麼變化
HTTP CONNECT 握手中,用戶端要求代理為目標 authority 建立位元組隧道。2xx 回應表示隧道建立成功;407 表示代理要求驗證,並可透過 Proxy-Authenticate 告知允許的方法。
合併後的修正阻止 CONNECT 解析器在回應為 401 時轉交或解讀 WWW-Authenticate。curl 會把它視為隧道失敗。補丁也新增專門的回歸測試,讓這項行為保持明確。
這是解析器與驗證邊界修正,不會新增驗證方式、不會繞過代理政策,也不會讓被拒絕的隧道取得無限重試資格。
為什麼必須區分 401 與 407
使用代理的用戶端通常持有兩套獨立憑證:
- 隧道建立前使用的代理憑證;
- 隧道建立後、只在隧道內部使用的目標憑證。
混用兩者會帶來安全與營運風險:用戶端可能把目標憑證送往代理層、反覆重試確定性拒絕、輪換健康出口,或錯誤地把事件歸類為目標登入失敗。共用連線池時,模糊的驗證狀態也會增加事故取證難度。
| CONNECT 結果 | 目前邊界含義 | 用戶端動作 |
|---|---|---|
| 2xx | 隧道已建立 | 繼續目標協定 |
| 407 加 Proxy-Authenticate | 代理要求驗證 | 僅使用核准的代理憑證並限制協商次數 |
| 401 加 WWW-Authenticate | 不應驅動代理驗證 | 讓隧道失敗,不把它當成代理挑戰 |
| 其他非 2xx | 隧道未建立 | 記錄狀態並執行失敗政策 |
curl CONNECT 尾端欄位測試指南說明相鄰的回應邊界;SPNEGO 與 NTLM 回退文章介紹另一項代理驗證強化。
建立受控回歸環境
使用自己擁有或獲准測試的代理模擬器與目標服務。並行設為 1,關閉自動閘道輪換,讓每個結果只有一個原因。準備四種代理行為:
- 回傳正常 2xx CONNECT 並轉送隧道。
- 回傳 407 與受支援的
Proxy-Authenticate挑戰。 - 回傳 401、帶有
WWW-Authenticate,隨後關閉連線。 - 回傳另一種確定性的非 2xx,且不帶驗證標頭。
分別使用目前正式環境建置與包含修正的建置執行全部案例。不要在無關公共代理上製造異常驗證回應。
應記錄哪些證據
記錄用戶端版本、建置識別碼、TLS 後端、代理傳輸方式、閘道群組、位址家族與時間。CONNECT 交換只保留去識別化欄位:
- 回應狀態;
- 是否出現
Proxy-Authenticate或WWW-Authenticate; - 最終選擇的代理驗證方法;
- CONNECT 嘗試次數;
- curl 結果碼與總耗時;
- 是否送出任何目標 TLS 位元組;
- 是否嘗試直接連線。
不得記錄使用者名稱、密碼、Bearer Token、原始 Authorization 值、Cookie 或完整工作階段識別碼。不需要原始位址時,應將閘道與出口識別碼代碼化。
通過與失敗標準
2xx 案例只有在預期代理路徑上的目標 TLS 與應用檢查都成功時才算通過。407 案例應使用正確作用域的代理憑證,在重試上限內完成允許的驗證流程並建立隧道。
401 案例應在不回應 WWW-Authenticate、不送出目標憑證、不進入目標 TLS、也不靜默直接連線的情況下讓 CONNECT 失敗。只有通用失敗碼仍不足夠,必須確認沒有驗證重試。
另一個非 2xx 案例應以一次可歸因結果結束。面對相同確定性回應仍不斷輪換出口,代表重試政策本身有問題。
不混淆用戶端與網路健康的發布方式
先在小型金絲雀群組部署,並與使用相同代理閘道、目標與工作負載的對照組比較:
- 首次嘗試有效結果率;
- CONNECT 狀態分布;
- 代理驗證挑戰輪數;
- 憑證越界次數,預期為零;
- 直接連線回退次數,預期為零;
- 隧道建立耗時 p50 與 p95;
- 每個完成工作的重試量。
若用戶端升級後 401 失敗增加,不要立即歸咎於出口品質。更嚴格的用戶端可能揭露了回傳來源站式驗證的閘道、中介設備或測試夾具。保留去識別化回應,定位真正產生它的元件。
上線前檢查清單
- 確認實際二進位檔是否包含已合併修正。
- 在設定與日誌中分離代理憑證和目標憑證。
- 涵蓋 2xx、407、401 與另一種非 2xx。
- 確認 401 不觸發驗證重試。
- 確認 CONNECT 失敗絕不回退直接連線。
- 限制重試,不因確定性的用戶端政策失敗懲罰出口。
- 清除所有憑證與高基數工作階段值。
- 擴大部署前,將金絲雀群組與目前用戶端對照。
常見問題
代理是否絕對不能回傳 401?
CONNECT 期間的代理驗證應使用 407。401 屬於來源站驗證語義,不應驅動代理憑證協商。
修正是否已包含在 curl 8.22.0?
不能根據開發發布說明這樣推斷。修正在 8.22.0 之後合併並列入下一版本;請檢查具體二進位檔與供應商回移補丁。
401 是否應觸發住宅代理出口輪換?
不應自動輪換。先把它歸類為隧道邊界失敗,查明產生回應的元件。盲目輪換會掩蓋確定性的閘道或用戶端政策問題。
除錯日誌可以保存驗證標頭嗎?
只記錄標頭名稱與去識別化的方法標籤。除非經核准的安全流程明確要求,否則不要保存憑證、Token 或原始挑戰內容。
合規說明
只在你擁有或獲准測試的系統與代理服務中執行此流程。遵守目標條款、存取控制、速率限制、隱私義務與資料最小化要求。目標是確保驗證作用域正確和失敗處理可靠,而不是繞過拒絕。