Nginx 1.26 異動總覽
Nginx 1.26 版推出後,我們進行了幾項重大異動,以提升安全性並確保符合 HTTP 標準。主要更新內容如下:
處理標頭名稱和值中的空白字元
為提升安全性,我們已加強遵守 RFC 7230 規範,特別是標頭中的空白字元處理方式。如要進一步瞭解這些異動,請參閱附錄。
處理 Content-Length
和 Transfer-Encoding
標頭
要求走私攻擊中常見的技術之一,是傳送同時含有 Content-Length
和 Transfer-Encoding
標頭的 HTTP 要求。雖然 Apigee Edge 已經能抵禦這類攻擊,但 Nginx 現在會明確封鎖同時包含這兩個標頭的要求。如果傳送這類要求,Nginx 會以 400 Bad Request 錯誤回應。
支援的加密方式
本次發布後,北向要求支援的密碼清單可能會有所變更。你可以在路由器主機上查看 OpenSSL 支援的密碼,取得可用密碼的最新清單。
支援的金鑰大小
先前,系統預設接受小於 2048 位元的 RSA、DSA 和 DH 金鑰,以及小於 224 位元的 ECC 金鑰。不過,這項異動生效後,北向要求的一方和雙向 TLS 連線將不再允許使用這類金鑰。
附錄
標頭中的空白字元
主要異動如下:
- Nginx 1.26 現在禁止使用某些先前允許的標頭名稱。如果要求包含這些標頭,會導致 400 Bad Request 錯誤。
- Nginx 1.26 現在禁止使用先前允許的特定標頭值。如果要求包含這些標頭,也會導致 400 Bad Request 錯誤。
- Nginx 之前會接受某些標頭,但這些標頭會導致訊息處理器下游發生故障,現在 Nginx 會直接拒絕這類標頭。雖然這些標頭仍會導致 API 失敗,但 HTTP 失敗訊息會有所不同。
以下章節提供各種不允許的標頭名稱和標頭值範例。清單中僅列舉部分檢查事項,僅供參考之用。建議您遵守 RFC 7230 的標頭指南。
標頭名稱變更
本節列出 Nginx 1.20.1 允許但 Nginx 1.26 不允許的各種標頭名稱。
情境 | 標頭名稱範例 |
---|---|
標頭名稱開頭、結尾或中間的控制字元 | { '\u0001'Header0, Value0 } { Header6'\u0002', Value6 } { Header'\u0005'4, Value4 } |
標頭名稱開頭和結尾的空白字元 | {"Header2 ", "Value2"} {" Header3", "Value3"} {" Header4 ", "Value4"} |
標頭名稱開頭和結尾的 HTAB | {"\tHeader11", "Value11"} {"Header12\t", "Value12"} {"\tHeader13\t", "Value13"} |
標頭名稱中 HTAB 和 WS 的開頭和結尾組合 | {"\t Header24", "Value24"} {" \tHeader25", "Value25"} {"Header26 \t", "Value26"} {"Header27\t ", "Value27"} |
標頭名稱後方緊接著換行符號 (\n),然後是 WS 或一連串 WS | {"Header\n 57Mutiline", "Value57"} {"Header\n 58Mutiline", "Value58"} |
標頭名稱之間有 NewLine (\n),且緊接在 HTAB 或一系列 HTAB 後面 | {"Header\n\t73", "Value73"} {"Header\n\t\t74", "Value74"} |
標頭名稱後方緊接 HTAB 或一連串 HTAB,中間有回車字元 (\r) NewLine (\n) | {"Header\r\n\t69", "Value69"} {"Header\r\n\t\t70", "Value70"} |
標頭名稱後方緊接著 WS 或一連串 WS,中間有回車字元 (\r) NewLine (\n) | {"Header\r\n 71", "Value71"} {"Header\r\n 72", "Value72"} |
標題值變更
這個部分會顯示 Nginx 1.20.1 允許但 Nginx 1.26 不允許的各種標頭值。
情境 | 範例 |
---|---|
\r\n 或 \r\n 與 WS 或 HTAB 的組合,允許在 HEADERVALUE 之間 |
{"Header47", "Value47\r\n MultiLine"}, {"Header48", "Value48\r\n MultiLine"}, {"Header49b", "Value49b\r\n \r\nMultiLine"}, {"Header50", "Value50 \r\n MultiLine"}, {"Header51", "Value51\r\n\tMultiLine"}, {"Header52", "Value52\r\n\t\tMultiLine"}, {"Header53", "Value53\t\r\n\tMultiLine"} |
\n 或 \n 與 WS 或 HTAB 的組合,允許在 HEADERVALUE 之間 |
{"Header61", "Value\n 61Multiline"}, {"Header62", "Value\n 63Multiline"}, {"Header65", "Value\n\t65"}, {"Header66", "Value\n\t\t66"}, {"Header67", "Value\n 67"}, {"Header68", "Value\n 68"} |
HTTP 失敗回應的變化
本節涵蓋舊版 Nginx 允許但上游訊息處理器拒絕的標頭,導致狀態碼為 400。不過,在 Nginx 1.26 中,這類標頭會直接導致 Nginx 發生故障,因此要求無法轉送至訊息處理器。
對於傳送這類標頭的用戶端,HTTP 狀態碼仍為 400。不過,HTTP 回應主體可能會有所不同,因為現在失敗是由 Nginx 產生,而不是訊息處理器。
情境 | 範例 |
---|---|
HEADERNAME 之間有 HTAB 或 WS
訊息處理器會拒絕這類要求。使用 Nginx 1.26 時,Nginx 本身會拒絕這些要求。API 消費者會收到 400 錯誤回應,內文包含 Nginx 錯誤訊息。 |
{"Header 5", "Value5"}, {"Header\t14", "Value14"}, {"Header\t 32", "Value32"}, {"Header \t33", "Value33"}, {"Header- 36", "Value36"}, {"Header-\t40", "Value40"}, {"Header 4a", "Value4a"}, {"Header\t 59", "Value59"}, {"Header\t 60", "Value60"} |