安全 HTTP 響應頭

本文件的這部分討論了安全 HTTP 響應頭的一般主題。有關基於 Servlet基於 WebFlux 的應用中安全 HTTP 響應頭的具體資訊,請參見相關章節。

您可以透過多種方式使用 HTTP 響應頭來增強 Web 應用的安全性。本節專門介紹 Spring Security 明確支援的各種 HTTP 響應頭。如果需要,您還可以配置 Spring Security 來提供自定義頭

預設安全頭

有關如何為基於 Servlet基於 WebFlux 的應用自定義預設配置,請參見相關章節。

Spring Security 提供了一組預設的安全相關 HTTP 響應頭,以提供安全的預設配置。

Spring Security 預設包含以下頭

預設安全 HTTP 響應頭
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-XSS-Protection: 0

Strict-Transport-Security 僅在 HTTPS 請求中新增

如果預設設定不符合您的需求,您可以輕鬆地從這些預設設定中移除、修改或新增頭。有關每個頭的更多詳細資訊,請參見相應章節

快取控制

有關如何為基於 Servlet基於 WebFlux 的應用自定義預設配置,請參見相關章節。

Spring Security 預設停用快取以保護使用者內容。

如果使用者認證後檢視敏感資訊然後登出,我們不希望惡意使用者能夠點選返回按鈕檢視敏感資訊。預設傳送的快取控制頭包括

預設快取控制 HTTP 響應頭
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0

為實現預設安全,Spring Security 預設新增這些頭。但是,如果您的應用提供了自己的快取控制頭,Spring Security 會讓出控制權。這使得應用能夠確保靜態資源(如 CSS 和 JavaScript)可以被快取。

內容型別選項

有關如何為基於 Servlet基於 WebFlux 的應用自定義預設配置,請參閱相關章節。

從歷史上看,包括 Internet Explorer 在內的瀏覽器會嘗試透過內容嗅探來猜測請求的內容型別。這使得瀏覽器可以透過猜測未指定內容型別的資源的內容型別來改善使用者體驗。例如,如果瀏覽器遇到一個未指定內容型別的 JavaScript 檔案,它就能猜測出內容型別然後執行它。

允許上傳內容時,還有許多其他應該採取的措施(例如,僅在不同域中顯示文件、確保設定 Content-Type 頭、清理文件等)。但是,這些措施超出了 Spring Security 的提供範圍。同樣重要的是要指出,停用內容嗅探時,您必須指定內容型別,以確保一切正常工作。

內容嗅探的問題在於它允許惡意使用者使用 polyglots(即,一個檔案同時滿足多種內容型別的有效性)來執行 XSS 攻擊。例如,某些網站可能允許使用者提交有效的 Postscript 文件並檢視它。惡意使用者可能建立一個既是 Postscript 文件又是有效 JavaScript 檔案的 polyglot,並用它進行 XSS 攻擊。

預設情況下,Spring Security 透過向 HTTP 響應新增以下頭來停用內容嗅探

nosniff HTTP 響應頭
X-Content-Type-Options: nosniff

HTTP Strict Transport Security (HSTS)

有關如何為基於 Servlet基於 WebFlux 的應用自定義預設配置,請參閱相關章節。

當您輸入銀行網站時,您輸入的是 mybank.example.com 還是 https://mybank.example.com?如果您省略了 https 協議,您可能會受到中間人攻擊 (Man-in-the-Middle attacks)。即使網站會重定向到 https://mybank.example.com,惡意使用者也可能攔截最初的 HTTP 請求並操縱響應(例如,重定向到 https://mibank.example.com 並竊取其憑據)。

許多使用者省略了 https 協議,這就是建立HTTP Strict Transport Security (HSTS) 的原因。一旦 mybank.example.com 被新增為 HSTS 主機,瀏覽器就能提前知道任何傳送到 mybank.example.com 的請求都應該被解釋為 https://mybank.example.com。這大大降低了發生中間人攻擊的可能性。

根據RFC6797,HSTS 頭僅注入到 HTTPS 響應中。為了讓瀏覽器識別該頭,瀏覽器必須首先信任用於建立連線的 SSL 證書的 CA(而不僅僅是 SSL 證書)。

將網站標記為 HSTS 主機的一種方式是將主機預載入到瀏覽器中。另一種方式是向響應中新增 Strict-Transport-Security 頭。例如,Spring Security 的預設行為是新增以下頭,該頭指示瀏覽器將該域視為 HSTS 主機一年(非閏年有 31536000 秒)

Strict Transport Security HTTP 響應頭
Strict-Transport-Security: max-age=31536000 ; includeSubDomains ; preload

可選的 includeSubDomains 指令指示瀏覽器也應將子域(例如 secure.mybank.example.com)視為 HSTS 域。

可選的 preload 指令指示瀏覽器應將該域預載入為 HSTS 域。有關 HSTS 預載入的更多詳細資訊,請參見 hstspreload.org

HTTP 公鑰鎖定 (HPKP)

為了保持被動,Spring Security 仍然提供在 Servlet 環境中對 HPKP 的支援。但是,由於前面列出的原因,Spring Security 團隊不再推薦使用 HPKP。

HTTP 公鑰鎖定 (HPKP) 向 Web 客戶端指定使用某個 Web 伺服器時應使用哪個公鑰,以防止偽造證書的中間人 (MITM) 攻擊。如果正確使用,HPKP 可以為防禦受損證書增加額外的保護層。然而,由於 HPKP 的複雜性,許多專家不再推薦使用它,甚至Chrome 也已經取消了對其的支援

有關不再推薦 HPKP 的更多詳細資訊,請閱讀HTTP 公鑰鎖定已死? 以及我放棄使用 HPKP

X-Frame-Options

有關如何為基於 Servlet基於 WebFlux 的應用自定義預設配置,請參見相關章節。

允許您的網站被新增到框架中可能會帶來安全問題。例如,透過巧妙的 CSS 樣式,使用者可能會被欺騙點選並非他們本意的內容。例如,登入銀行的使用者可能會點選一個授予其他使用者訪問許可權的按鈕。這種攻擊被稱為點選劫持 (Clickjacking)

處理點選劫持的另一種現代方法是使用內容安全策略 (CSP)

有多種方法可以緩解點選劫持攻擊。例如,為了保護舊版瀏覽器免受點選劫持攻擊,您可以使用框架破壞程式碼。雖然不完美,但框架破壞程式碼是您能為舊版瀏覽器做的最好的事情。

解決點選劫持的一種更現代的方法是使用X-Frame-Options 頭。預設情況下,Spring Security 透過使用以下頭來停用在 iframe 中渲染頁面

X-Frame-Options: DENY

X-XSS-Protection

有關如何為基於 Servlet基於 WebFlux 的應用自定義預設配置,請參見相關章節。

一些瀏覽器內建了過濾反射型 XSS 攻擊的支援。該過濾器在主要瀏覽器中已被棄用,當前的 OWASP 建議是明確將該頭設定為 0。

預設情況下,Spring Security 透過使用以下頭來阻止內容

X-XSS-Protection: 0

內容安全策略 (CSP)

有關如何為基於 Servlet基於 WebFlux 的應用配置,請參見相關章節。

內容安全策略 (CSP) 是一種機制,Web 應用可以使用它來緩解內容注入漏洞,例如跨站指令碼 (XSS)。CSP 是一種宣告性策略,為 Web 應用作者提供了一種設施,用於宣告並最終通知客戶端(使用者代理)Web 應用預期從哪些來源載入資源。

內容安全策略並非旨在解決所有內容注入漏洞。相反,您可以使用 CSP 來幫助減少內容注入攻擊造成的損害。作為第一道防線,Web 應用作者應該驗證其輸入並對輸出進行編碼。

Web 應用可以透過在響應中包含以下 HTTP 頭之一來使用 CSP

  • Content-Security-Policy

  • Content-Security-Policy-Report-Only

每個頭都用作向客戶端傳遞安全策略的機制。安全策略包含一組安全策略指令,每個指令負責宣告特定資源表示的限制。

例如,Web 應用可以透過在響應中包含以下頭來宣告它預期從特定的受信任來源載入指令碼

內容安全策略示例
Content-Security-Policy: script-src https://trustedscripts.example.com

使用者代理會阻止嘗試從 script-src 指令中宣告的來源以外的任何其他來源載入指令碼。此外,如果在安全策略中聲明瞭report-uri 指令,使用者代理會將違規行為報告給宣告的 URL。

例如,如果 Web 應用違反了宣告的安全策略,以下響應頭指示使用者代理將違規報告發送到策略的 report-uri 指令中指定的 URL。

帶 report-uri 的內容安全策略
Content-Security-Policy: script-src https://trustedscripts.example.com; report-uri /csp-report-endpoint/

違規報告是標準的 JSON 結構,可以透過 Web 應用自己的 API 或公共託管的 CSP 違規報告服務(例如report-uri.io/)捕獲。

Content-Security-Policy-Report-Only 頭為 Web 應用作者和管理員提供了監視安全策略而不是強制執行策略的能力。此頭通常在為網站試驗或開發安全策略時使用。當策略被認為有效時,可以使用 Content-Security-Policy 頭欄位來強制執行它。

考慮以下響應頭,該策略宣告指令碼可以從兩個可能的來源之一載入。

僅報告內容安全策略
Content-Security-Policy-Report-Only: script-src 'self' https://trustedscripts.example.com; report-uri /csp-report-endpoint/

如果網站違反此策略,嘗試從 evil.example.com 載入指令碼,使用者代理會將違規報告發送到 report-uri 指令指定的宣告 URL,但仍允許載入違規資源。

將內容安全策略應用於 Web 應用通常是一項非易事的任務。以下資源可能有助於為您的網站制定有效的安全策略

Referrer Policy

有關如何為基於 Servlet基於 WebFlux 的應用配置,請參見相關章節。

Referrer Policy 是一種機制,Web 應用可以使用它來管理 referrer 欄位,該欄位包含使用者上次所在的頁面。

Spring Security 的方法是使用Referrer Policy 頭,該頭提供了不同的策略

Referrer Policy 示例
Referrer-Policy: same-origin

Referrer-Policy 響應頭指示瀏覽器告知目的地使用者之前所在的來源。

Feature Policy

有關如何為基於 Servlet基於 WebFlux 的應用配置,請參見相關章節。

Feature Policy 是一種機制,允許 Web 開發者選擇性地啟用、停用和修改瀏覽器中某些 API 和 Web 特性的行為。

Feature Policy 示例
Feature-Policy: geolocation 'self'

使用 Feature Policy,開發者可以為瀏覽器選擇啟用一組“策略”,以便在整個網站中使用的特定特性上強制執行。這些策略限制了網站可以訪問哪些 API 或修改某些特性的瀏覽器預設行為。

Permissions Policy

有關如何為基於 Servlet基於 WebFlux 的應用配置,請參見相關章節。

Permissions Policy 是一種機制,允許 Web 開發者選擇性地啟用、停用和修改瀏覽器中某些 API 和 Web 特性的行為。

Permissions Policy 示例
Permissions-Policy: geolocation=(self)

使用 Permissions Policy,開發者可以為瀏覽器選擇啟用一組“策略”,以便在整個網站中使用的特定特性上強制執行。這些策略限制了網站可以訪問哪些 API 或修改某些特性的瀏覽器預設行為。

Clear Site Data

有關如何為基於 Servlet基於 WebFlux 的應用配置,請參見相關章節。

Clear Site Data 是一種機制,當 HTTP 響應包含此頭時,可以刪除任何瀏覽器端資料(cookies、本地儲存等)

Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"

這是登出時執行的一個不錯的清理操作。

自定義頭

有關如何為基於 Servlet 的應用進行配置,請參見相關章節。

Spring Security 提供了方便的機制,可以輕鬆地將更常見的安全頭新增到您的應用中。此外,它還提供了啟用新增自定義頭的鉤子。