1. 程式人生 > >內容安全策略(CSP)詳解

內容安全策略(CSP)詳解

內容安全策略(CSP),其核心思想十分簡單:網站通過傳送一個 CSP 頭部,來告訴瀏覽器什麼是被授權執行的與什麼是需要被禁止的。其被譽為專門為解決XSS攻擊而生的神器。

1.CSP是什麼

CSP指的是內容安全策略,為了緩解很大一部分潛在的跨站指令碼問題,瀏覽器的擴充套件程式系統引入了內容安全策略(CSP)的一般概念。這將引入一些相當嚴格的策略,會使擴充套件程式在預設情況下更加安全,開發者可以建立並強制應用一些規則,管理網站允許載入的內容。簡單來說,就是我們能夠規定,我們的網站只接受我們指定的請求資源。

2. CSP的意義

防XSS等攻擊的利器。CSP 的實質就是白名單制度,開發者明確告訴客戶端,哪些外部資源可以載入和執行,等同於提供白名單。它的實現和執行全部由瀏覽器完成,開發者只需提供配置。CSP 大大增強了網頁的安全性。攻擊者即使發現了漏洞,也沒法注入指令碼,除非還控制了一臺列入了白名單的可信主機。

3.CSP的分類

(1)Content-Security-Policy
配置好並啟用後,不符合 CSP 的外部資源就會被阻止載入。
(2)Content-Security-Policy-Report-Only
表示不執行限制選項,只是記錄違反限制的行為。它必須與report-uri選項配合使用。

4.CSP的使用

(1)在HTTP Header上使用(首選)

"Content-Security-Policy:" 策略
"Content-Security-Policy-Report-Only:" 策略

(2)在HTML上使用

<meta http-equiv="content-security-policy"
content="策略">
<meta http-equiv="content-security-policy-report-only" content="策略">

Meta 標籤與 HTTP 頭只是行式不同而作用是一致的,如果 HTTP 頭與 Meta 定義同時存在,則優先採用 HTTP 中的定義。
如果使用者瀏覽器已經為當前文件執行了一個 CSP 的策略,則會跳過 Meta 的定義。如果 META 標籤缺少 content 屬性也同樣會跳過。

5.策略應該怎麼寫

(1)舉個例子

// 限制所有的外部資源,都只能從當前域名載入
Content-Security-Policy
: default-src 'self'
// default-src 是 CSP 指令,多個指令之間用英文分號分割;多個指令值用英文空格分割
Content-Security-Policy: default-src https://host1.com https://host2.com; frame-src 'none'; object-src 'none'  
// 錯誤寫法,第二個指令將會被忽略
Content-Security-Policy: script-src https://host1.com; script-src https://host2.com

// 正確寫法如下
Content-Security-Policy: script-src https://host1.com https://host2.com
// 通過report-uri指令指示瀏覽器傳送JSON格式的攔截報告到某個地址
Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser; 

// 報告看起來會像下面這樣
{  
  "csp-report": {  
    "document-uri": "http://example.org/page.html",  
    "referrer": "http://evil.example.com/",  
    "blocked-uri": "http://evil.example.com/evil.js",  
    "violated-directive": "script-src 'self' https://apis.google.com",  
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"  
  }  
}  

(2)常用的CSP指令

指令 指令和指令值示例 指令說明
default-src ‘self’ cdn.guangzhul.com 預設載入策略
script-src ‘self’ js.guangzhul.com 對 JavaScript 的載入策略。
style-src ‘self’ css.guangzhul.com 對樣式的載入策略。
img-src ‘self’ img.guangzhul.com 對圖片的載入策略。
connect-src ‘self’ 對 Ajax、WebSocket 等請求的載入策略。不允許的情況下,瀏覽器會模擬一個狀態為 400 的響應。
font-src font.cdn.guangzhul.com 針對 WebFont 的載入策略。
object-src ‘self’ 針對 、 或 等標籤引入的 flash 等外掛的載入策略。
media-src media.cdn.guangzhul.com 針對媒體引入的 HTML 多媒體的載入策略。
frame-src ‘self’ 針對 frame 的載入策略。
report-uri /report-uri 告訴瀏覽器如果請求的資源不被策略允許時,往哪個地址提交日誌資訊。 特別的:如果想讓瀏覽器只彙報日誌,不阻止任何內容,可以改用 Content-Security-Policy-Report-Only 頭。

(3)其他的CSP指令

指令 指令和指令值示例 指令說明
sandbox 設定沙盒環境
child-src 主要防禦 <frame>,<iframe>
form-action 主要防禦 <form>
frame-ancestors 主要防禦 <frame>,<iframe>,<object>,<embed>,<applet>
plugin-types 主要防禦 <object>,<embed>,<applet>

(4)CSP指令值

指令值 指令和指令值示例 指令值說明
* img-src * 允許任何內容。
‘none’ img-src ‘none’ 不允許任何內容。
‘self’ img-src ‘self’ 允許來自相同來源的內容(相同的協議、域名和埠)。
data: img-src data: 允許 data: 協議(如 base64 編碼的圖片)。
www.guangzhul.com img-src img.guangzhul.com 允許載入指定域名的資源。
*.guangzhul.com img-src *.guangzhul.com 允許載入 guangzhul.com 任何子域的資源。
‘unsafe-inline’ script-src ‘unsafe-inline’ 允許載入 inline 資源(例如常見的 style 屬性,onclick,inline js 和 inline css 等等)。
‘unsafe-eval’ script-src ‘unsafe-eval’ 允許載入動態 js 程式碼,例如 eval()。

6.支援問題

(1)CSP1相容性
瀏覽器可以很好地支援 CSP 1,全球高達94.66%,中國達到79.55%(截至2018年4月12日)。
CSP1相容性
(2)CSP2相容性
CSP 2還很新,支援相對少點,全球達81.11%,中國達到60.04%(截至2018年4月12日)。
CSP2相容性