內容安全策略 (CSP)
內容安全策略 (CSP) 是一種額外的安全層,有助於檢測和緩解某些型別的攻擊,包括跨站指令碼攻擊 (XSS) 和資料注入攻擊。這些攻擊被用於從資料盜竊到網站篡改,再到惡意軟體分發等各種目的。
CSP 旨在完全向後相容(除了 CSP 版本 2 中有一些明確提到的向後相容性不一致之處;更多詳細資訊在此第 1.1 節)。不支援 CSP 的瀏覽器仍然可以與實現 CSP 的伺服器一起工作,反之亦然。不支援 CSP 的瀏覽器會忽略它,照常執行;它們只會應用標準同源策略的保護,而不會新增 CSP 會新增的進一步限制。
要啟用 CSP,您需要配置您的 Web 伺服器以返回Content-Security-Policy HTTP 標頭。(有時您可能會看到X-Content-Security-Policy標頭的提及,但那是舊版本,您不再需要指定它。)
或者,可以使用<meta>元素配置策略,例如
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; img-src https://*; child-src 'none';" />
注意:某些功能,例如傳送 CSP 違規報告,僅在使用 HTTP 標頭時可用。
威脅
緩解跨站指令碼攻擊
CSP 的主要目標是緩解和報告 XSS 攻擊。XSS 攻擊利用瀏覽器對從伺服器接收到的內容的信任。惡意指令碼由受害者的瀏覽器執行,因為瀏覽器信任內容的來源,即使它並非來自看起來的來源。
CSP 使伺服器管理員能夠透過指定瀏覽器應認為是可執行指令碼的有效來源的域來減少或消除 XSS 可能發生的途徑。然後,相容 CSP 的瀏覽器只會執行從這些允許的域接收到的原始檔中載入的指令碼,忽略所有其他指令碼(包括內聯指令碼和事件處理 HTML 屬性)。
作為一種終極保護形式,希望永遠不允許執行指令碼的站點可以選擇全域性禁止指令碼執行。
緩解資料包嗅探攻擊
除了限制可以從中載入內容的域之外,伺服器還可以指定允許使用哪些協議;例如(從安全的角度來看,理想情況下),伺服器可以指定所有內容都必須使用 HTTPS 載入。完整的的資料傳輸安全策略不僅包括強制執行 HTTPS 進行資料傳輸,還包括標記所有帶有secure屬性的 Cookie,並提供從 HTTP 頁面到其 HTTPS 對應頁面的自動重定向。站點還可以使用Strict-Transport-Security HTTP 標頭來確保瀏覽器僅透過加密通道連線到它們。
使用 CSP
配置內容安全策略涉及將Content-Security-Policy HTTP 標頭新增到網頁中,並賦予其值以控制使用者代理允許為該頁面載入哪些資源。例如,上傳和顯示影像的頁面可以允許來自任何地方的影像,但將表單操作限制到特定端點。正確設計的內容安全策略有助於保護頁面免受跨站指令碼攻擊。本文介紹瞭如何正確構造此類標頭,並提供了示例。
指定您的策略
您可以使用Content-Security-Policy HTTP 標頭指定您的策略,如下所示
Content-Security-Policy: policy
策略是一個包含策略指令的字串,描述您的內容安全策略。
編寫策略
策略使用一系列策略指令來描述,每個指令描述特定資源型別或策略區域的策略。您的策略應包含default-src策略指令,當其他資源型別沒有自己的策略時,它作為後備(有關完整列表,請參閱default-src指令的描述)。策略需要包含default-src或script-src指令以防止內聯指令碼執行,以及阻止使用eval()。策略需要包含default-src或style-src指令以限制從<style>元素或style屬性應用內聯樣式。針對各種型別的專案有特定的指令,以便每種型別都可以有自己的策略,包括字型、框架、影像、音訊和影片媒體、指令碼和工作執行緒。
有關策略指令的完整列表,請參閱Content-Security-Policy 標頭的參考頁面。
示例:常見用例
本節提供了一些常見安全策略場景的示例。
示例 1
網站管理員希望所有內容都來自網站自己的來源(這排除了子域)。
Content-Security-Policy: default-src 'self'
示例 2
網站管理員希望允許來自受信任域及其所有子域的內容(不必與設定 CSP 的域相同)。
Content-Security-Policy: default-src 'self' example.com *.example.com
示例 3
網站管理員希望允許 Web 應用程式的使用者在其自己的內容中包含來自任何來源的影像,但將音訊或影片媒體限制為受信任的提供商,並將所有指令碼僅限於託管受信任程式碼的特定伺服器。
Content-Security-Policy: default-src 'self'; img-src *; media-src example.org example.net; script-src userscripts.example.com
在這裡,預設情況下,內容僅允許來自文件的來源,以下情況除外
- 影像可以從任何地方載入(請注意“*”萬用字元)。
- 媒體僅允許來自 example.org 和 example.net(而非來自這些站點的子域)。
- 可執行指令碼僅允許來自 userscripts.example.com。
示例 4
線上銀行網站的網站管理員希望確保其所有內容都使用 TLS 載入,以防止攻擊者竊聽請求。
Content-Security-Policy: default-src https://onlinebanking.example.com
伺服器僅允許訪問透過單個來源 onlinebanking.example.com 透過 HTTPS 特定載入的文件。
示例 5
Web 郵件站點的網站管理員希望允許電子郵件中的 HTML 以及從任何地方載入的影像,但 JavaScript 或其他潛在的危險內容只能來自與郵件伺服器相同的來源。
Content-Security-Policy: default-src 'self' *.example.com; img-src *
請注意,此示例未指定script-src,因此default-src指令將用作 JavaScript 源的後備。
測試您的策略
為了簡化部署,CSP 可以以報告模式部署。策略不會被執行,但任何違規行為都會報告到提供的 URI。此外,可以使用僅報告標頭來測試策略的未來修訂版,而無需實際部署它。
您可以使用Content-Security-Policy-Report-Only HTTP 標頭指定您的策略,如下所示
Content-Security-Policy-Report-Only: policy
如果在同一個響應中同時存在Content-Security-Policy-Report-Only標頭和Content-Security-Policy標頭,則兩個策略都會被遵守。Content-Security-Policy標頭中指定的策略會被執行,而Content-Security-Policy-Report-Only策略會生成報告,但不會被執行。
違規報告
報告 CSP 違規的推薦方法是使用Reporting API,在Reporting-Endpoints中宣告端點,並使用Content-Security-Policy標頭的report-to指令將其中一個指定為 CSP 報告目標。
警告:您還可以使用 CSP report-uri指令指定 CSP 違規報告的目標 URL。這透過帶有application/csp-report的Content-Type的POST操作傳送略有不同的 JSON 報告格式。這種方法已棄用,但您應該同時宣告兩者,直到report-to在所有瀏覽器中都得到支援。有關此方法的更多資訊,請參閱report-uri主題。
伺服器可以使用Reporting-Endpoints HTTP 響應標頭通知客戶端傳送報告的位置。此標頭將一個或多個端點 URL 定義為逗號分隔列表。例如,要定義名為csp-endpoint的報告端點,該端點在https://example.com/csp-reports處接受報告,伺服器的響應標頭可能如下所示
Reporting-Endpoints: csp-endpoint="https://example.com/csp-reports"
如果您希望有多個處理不同型別報告的端點,則會像這樣指定它們
Reporting-Endpoints: csp-endpoint="https://example.com/csp-reports",
hpkp-endpoint="https://example.com/hpkp-reports"
然後,您可以使用Content-Security-Policy標頭的report-to指令指定應將特定定義的端點用於報告。例如,要將 CSP 違規報告發送到https://example.com/csp-reports以用於default-src,您可能會發送如下所示的響應標頭
Reporting-Endpoints: csp-endpoint="https://example.com/csp-reports"
Content-Security-Policy: default-src 'self'; report-to csp-endpoint
發生 CSP 違規時,瀏覽器會將報告作為 JSON 物件透過 HTTP POST操作傳送到指定的端點,並使用application/reports+json的Content-Type。報告是包含值為“csp-violation”的type屬性以及作為CSPViolationReportBody物件的序列化形式的body的Report物件的序列化形式。
一個典型的物件可能如下所示
{
"age": 53531,
"body": {
"blockedURL": "inline",
"columnNumber": 39,
"disposition": "enforce",
"documentURL": "https://example.com/csp-report",
"effectiveDirective": "script-src-elem",
"lineNumber": 121,
"originalPolicy": "default-src 'self'; report-to csp-endpoint-name",
"referrer": "https://www.google.com/",
"sample": "console.log(\"lo\")",
"sourceFile": "https://example.com/csp-report",
"statusCode": 200
},
"type": "csp-violation",
"url": "https://example.com/csp-report",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
}
您需要設定一個伺服器來接收使用給定 JSON 格式和內容型別的報告。處理這些請求的伺服器可以以最適合您需求的方式儲存或處理傳入的報告。
瀏覽器相容性
BCD 表格僅在啟用
相容性說明
Safari 瀏覽器的一些版本存在特定不相容性,即如果設定了內容安全策略標頭,但未設定同源標頭,則瀏覽器將阻止自託管內容和異地內容,並錯誤地報告這是由於內容安全策略不允許該內容導致的。
另請參閱
Content-Security-PolicyHTTP 標頭Content-Security-Policy-Report-OnlyHTTP 標頭- WebExtensions 中的內容安全
- Web Workers 中的 CSP
- 隱私、許可權和資訊安全
- CSP 評估器 - 評估您的內容安全策略