內容安全策略 (CSP) 是一個額外的安全層,用於檢測並削弱某些特定類型的攻擊,包括跨站腳本 (XSS) 和數據注入攻擊等。無論是數據盜取、網站內容污染還是散發惡意軟件,這些攻擊都是主要的手段。
內容源
大多數策略指令需要一個或多個內容源。內容源是一串表明內容可能從哪裏加載的字符串。
源列表
源列表是一個字符串,指定了一個或多個互聯網主機(通過主機名或 IP 地址),和可選的 URL 協議和/或端口號。站點地址可以包含可選的通配符前綴 (星號, '*'
),端口號也可以使用通配符 (同樣是 '*'
) 來表明所有合法端口都是有效來源。主機通過空格分隔。
有效的主機表達式包括:
- http://*.foo.com
- 匹配所有使用
http:
協議加載 foo.com 任何子域名的嘗試。 - mail.foo.com:443
- 匹配所有訪問 mail.foo.com 的 443 端口 的嘗試。
- https://store.foo.com
- 匹配所有使用
https:
協議訪問 store.foo.com 的嘗試。
如果端口號沒有被指定,瀏覽器會使用指定協議的默認端口號。如果協議沒有被指定,瀏覽器會使用訪問該文檔時的協議。
關鍵字
有一些關鍵字可以用來描述某類特別的內容源。它們是:
'none'
- 代表空集;即不匹配任何 URL。兩側單引號是必須的。
'self'
- 代表和文檔同源,包括相同的 URL 協議和端口號。兩側單引號是必須的。
'unsafe-inline'
- 允許使用內聯資源,如內聯的
<script>
元素、javascript:
URL、內聯的事件處理函數和內聯的<style>
元素。兩側單引號是必須的。 'unsafe-eval'
- 允許使用
eval()
等通過字符串創建代碼的方法。兩側單引號是必須的。
例如,您可以指定內容能從文檔源和 trustedscripts.foo.com 加載:
Content-Security-Policy: default-src 'self' trustedscripts.foo.com
數據
data:
URI 是不安全的,如果它們被允許成爲腳本來源,則會使您的網站有跨站腳本攻擊風險。- data:
- 允許
data:
URI 作爲內容來源。這是不安全的,因爲攻擊者可以精心構造 data: URI 來攻擊。請謹慎地使用這個源,並確保不要用於腳本。 - mediastream:
- 允許
mediastream:
URI 作爲內容源。
Content-Security-Policy: default-src 'self'; img-src 'self' data:; media-src mediastream:
CSP 被設計成完全向後兼容(除CSP2 在向後兼容有明確提及的不一致; 更多細節查看這裏 章節1.1)。不支持CSP的瀏覽器也能與實現了CSP的服務器正常合作,反之亦然:不支持 CSP 的瀏覽器只會忽略它,如常運行,默認爲網頁內容使用標準的同源策略。如果網站不提供 CSP 頭部,瀏覽器也使用標準的同源策略。
爲使CSP可用, 你需要配置你的網絡服務器返回 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';">
示例:常見用例
這一部分提供了一些常用的安全策略方案示例。
示例 1
一個網站管理者想要所有內容均來自站點的同一個源 (不包括其子域名)
Content-Security-Policy: default-src 'self'
示例 2
一個網站管理者允許內容來自信任的域名及其子域名 (域名不必須與CSP設置所在的域名相同)
Content-Security-Policy: default-src 'self' *.trusted.com
示例 3
一個網站管理者允許網頁應用的用戶在他們自己的內容中包含來自任何源的圖片, 但是限制音頻或視頻需從信任的資源提供者(獲得),所有腳本必須從特定主機服務器獲取可信的代碼.
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
在這裏,各種內容默認僅允許從文檔所在的源獲取, 但存在如下例外:
- 圖片可以從任何地方加載(注意 "*" 通配符)。
- 多媒體文件僅允許從 media1.com 和 media2.com 加載(不允許從這些站點的子域名)。
- 可運行腳本僅允許來自於userscripts.example.com。
示例 4
一個線上銀行網站的管理者想要確保網站的所有內容都要通過SSL方式獲取,以避免攻擊者竊聽用戶發出的請求。
Content-Security-Policy: default-src https://onlinebanking.jumbobank.com
該服務器僅允許通過HTTPS方式並僅從onlinebanking.jumbobank.com域名來訪問文檔。
示例 5
一個在線郵箱的管理者想要允許在郵件裏包含HTML,同樣圖片允許從任何地方加載,但不允許JavaScript或者其他潛在的危險內容(從任意位置加載)。
Content-Security-Policy: default-src 'self' *.mailsite.com; img-src *
注意這個示例並未指定script-src
。在此CSP示例中,站點通過 default-src
指令的對其進行配置,這也同樣意味着腳本文件僅允許從原始服務器獲取。
瀏覽器兼容性
Desktop | Mobile | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android webview | Chrome for Android | Edge Mobile | Firefox for Android | Opera for Android | iOS Safari | Samsung Internet | |
Content-Security-Policy | Full support25打開 | Full support14 | Full support23打開 | Full support10打開 | Full support15 | Full support7打開 | Full supportYes | Full supportYes | Full supportYes | Full support23 | ? | Full support7.1打開 | Full supportYes |
base-uri | Full support40 | No supportNo | Full support35 | No supportNo | Full support27 | Full support10 | Full supportYes | Full supportYes | No supportNo | Full support35 | ? | Full support9.3 | Full supportYes |
block-all-mixed-content | Full supportYes | ? | Full support48 | No supportNo | Full supportYes | ? | Full supportYes | Full supportYes | ? | Full support48 | ? | ? | Full supportYes |
child-src | Full support40 | Full support15 | Full support45 | No supportNo | Full support27 | Full support10 | Full supportYes | Full supportYes | No supportNo | Full support45 | ? | Full support9.3 | Full supportYes |
connect-src | Full support25 | Full support14 | Full support23打開 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
default-src | Full support25 | Full support14 | Full support23 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
disown-opener | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo |
font-src | Full support25 | Full support14 | Full support23 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
form-action | Full support40 | Full support15 | Full support36 | No supportNo | Full support27 | Full support10 | Full supportYes | Full supportYes | No supportNo | Full support36 | ? | Full support9.3 | Full supportYes |
frame-ancestors | Full support40 | Full support15 | Full support33打開 | No supportNo | Full support26 | Full support10 | ? | Full supportYes | No supportNo | Full support33打開 | ? | Full support9.3 | Full supportYes |
frame-src | Full support25 | Full support14 | Full support23 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
img-src | Full support25 | Full support14 | Full support23 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
manifest-src | Full supportYes | No supportNo | Full support41 | No supportNo | Full supportYes | No supportNo | Full supportYes | Full supportYes | No supportNo | Full support41 | ? | No supportNo | Full supportYes |
media-src | Full support25 | Full support14 | Full support23 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
navigation-to | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo |
object-src | Full support25 | Full support14 | Full support23 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
plugin-types | Full support40 | Full support15 | No supportNo打開 | No supportNo | Full support27 | Full support10 | Full supportYes | Full supportYes | No supportNo | No supportNo | ? | Full support9.3 | Full supportYes |
referrer | No support33 — 56 | No supportNo | Full support37打開 | No supportNo | No support? — 43 | No supportNo | No support33 — 56 | No support33 — 56 | No supportNo | Full support37打開 | No support? — 43 | No supportNo | Full supportYes |
report-sample | Full support59 | ? | ? | ? | Full support46 | ? | Full support59 | Full support59 | ? | ? | Full support46 | ? | Full support7.0 |
report-to | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo | No supportNo |
report-uri | Full support25 | Full support14 | Full support23 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
require-sri-for | Full support54 | No supportNo | Full support49打開 | No supportNo | Full support41 | No supportNo | Full support54 | Full support54 | No supportNo | Full support49打開 | Full support41 | No supportNo | Full support6.0 |
sandbox | Full support25 | Full support14 | Full support50 | Full support10 | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support50 | ? | Full support7.1 | Full supportYes |
script-src | Full support25 | Full support14 | Full support23 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
strict-dynamic | Full support52 | No supportNo | Full support52 | No supportNo | Full support39 | No supportNo | Full support52 | Full support52 | No supportNo | No supportNo | Full support39 | No supportNo | Full support6.0 |
style-src | Full support25 | Full support14 | Full support23 | No supportNo | Full support15 | Full support7 | Full supportYes | Full supportYes | ? | Full support23 | ? | Full support7.1 | Full supportYes |
upgrade-insecure-requests | Full support43 | No supportNo打開 | Full support42 | No supportNo | Full support30 | No supportNo | Full support43 | Full support43 | No supportNo | Full support42 | Full support30 | No supportNo | Full support4.0 |
worker-src | Full support59打開 | No supportNo | Full support58 | No supportNo | Full support48 | No supportNo | Full support59打開 | Full support59打開 | No supportNo | Full support58 | Full support48 | No supportNo | Full support7.0 |