跨域腳本攻擊 XSS 是最多見、危害最大的網頁安全漏洞。爲了防止它們,要採起不少編程措施,很是麻煩。不少人提出,能不能根本上解決問題,瀏覽器自動禁止外部注入惡意腳本?這就是"網頁安全政策"(Content Security Policy,縮寫 CSP)的來歷。內容安全策略(CSP),其核心思想十分簡單:網站經過發送一個 CSP 頭部,來告訴瀏覽器什麼是被受權執行的與什麼是須要被禁止的。其被譽爲專門爲解決XSS攻擊而生的神器。css
一、簡述html
在瀏覽網頁的過程當中,尤爲是移動端的網頁,常常看到有不少無關的廣告,其實大部分廣告都是所在的網絡劫持了網站響應的內容,並在其中植入了廣告代碼。爲了防止這種狀況發生,咱們可使用CSP來快速的阻止這種廣告植入。並且能夠比較好的防護dom xss。編程
CSP(Content Security Policy)指的是內容安全策略 ,是一個附加的安全層,用於幫助檢測和緩解某些類型的攻擊,包括跨站腳本攻擊 (XSS) 和數據注入等攻擊。這些攻擊可用於實現從數據竊取到網站破壞或做爲惡意軟件分發版本等用途。爲了緩解很大一部分潛在的跨站腳本問題,瀏覽器的擴展程序系統引入了內容安全策略(CSP)的通常概念。這將引入一些至關嚴格的策略,會使擴展程序在默認狀況下更加安全,開發者能夠建立並強制應用一些規則,管理網站容許加載的內容。簡單來講,就是咱們可以規定,咱們的網站只接受咱們指定的請求資源。api
內容安全策略在現代瀏覽器中已經包含,使用的是 W3C CSP 1.0 標準中描述的 Content-Security-Policy 頭部和指令。跨域
CSP的意義:防XSS等攻擊的利器。CSP 的實質就是白名單制度,開發者明確告訴客戶端,哪些外部資源能夠加載和執行,等同於提供白名單。它的實現和執行所有由瀏覽器完成,開發者只需提供配置。CSP 大大加強了網頁的安全性。攻擊者即便發現了漏洞,也無法注入腳本,除非還控制了一臺列入了白名單的可信主機。瀏覽器
CSP 能夠由兩種方式指定:HTTP Header 和 HTML。HTTP 是在 HTTP 由增長 Header 來指定,而 HTML 級別則由 Meta 標籤指定。安全
CSP 有兩類:Content-Security-Policy 和 Content-Security-Policy-Report-Only。(大小寫無關)服務器
(1)Content-Security-Policy:配置好並啓用後,不符合 CSP 的外部資源就會被阻止加載。網絡
(2)Content-Security-Policy-Report-Only:表示不執行限制選項,只是記錄違反限制的行爲。它必須與report-uri選項配合使用。app
HTTP header : "Content-Security-Policy:" 策略 "Content-Security-Policy-Report-Only:" 策略
HTTP Content-Security-Policy 頭能夠指定一個或多個資源是安全的,而Content-Security-Policy-Report-Only則是容許服務器檢查(非強制)一個策略。多個頭的策略定義由優先採用最早定義的。
HTML Meta : <meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only" content="策略">
Meta 標籤與 HTTP 頭只是行式不一樣而做用是一致的。與 HTTP 頭同樣,優先採用最早定義的策略。若是 HTTP 頭與 Meta 定義同時存在,則優先採用 HTTP 中的定義。若是用戶瀏覽器已經爲當前文檔執行了一個 CSP 的策略,則會跳過 Meta 的定義。若是 META 標籤缺乏 content 屬性也一樣會跳過。
針對開發者草案中特別的提示一點:爲了使用策略生效,應該將 Meta 元素頭放在開始位置,以防止提升人爲的 CSP 策略注入。
CSP使用方式有兩種
一、使用meta標籤, 直接在頁面添加meta標籤
<meta http-equiv="Content-Security-Policy" content="default-src 'self' *.xx.com *.xx.cn 'unsafe-inline' 'unsafe-eval';">
這種方式最簡單,可是也有些缺陷,每一個頁面都須要添加,並且不能對限制的域名進行上報。
二、在服務端配置csp
(1)Apache :
Add the following to your httpd.conf in your VirtualHost or in an .htaccess file:
Header set Content-Security-Policy "default-src 'self';"
(2)Nginx :
In your server {} block add:
add_header Content-Security-Policy "default-src 'self';";
在服務端配置全部的頁面均可以不須要改了,並且還支持上報。
若是meta、響應頭裏都指定了Content-Security-Policy,則會優先使用響應頭裏的Content-Security-Policy
CSP內容匹配的規則:規則名稱 規則 規則;規則名稱 規則 ...
好比:
default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';
default-src 'self' *.xx.com *.xx.cn aa.com 'unsafe-inline' 'unsafe-eval'
(*.xx.com 支持多級域名, 能夠不填寫http協議)
規則解釋:
default-src 全部資源的默認策略
script-src JS的加載策略,會覆蓋default-src中的策略,好比寫了default-src xx.com;script-src x.com xx.com; 必須同時加上xx.com,由於script-src會看成一個總體覆蓋整個默認的default-src規則。
'unsafe-inline' 容許執行內聯的JS代碼,默認爲不容許,若是有內聯的代碼必須加上這條
'unsafe-eval' 容許執行eval等
對自定義的協議 好比 jsxxx://aaa.com 能夠寫成 jsxxx:
https協議下自動把http請求轉爲https可使用 upgrade-insecure-requests
詳情配置及瀏覽器兼容性可查看官方文檔:https://content-security-policy.com
策略應該怎麼寫?示例
// 限制全部的外部資源,都只能從當前域名加載
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
有時,咱們不只但願防止 XSS,還但願記錄此類行爲。report-uri就用來告訴瀏覽器,應該把注入行爲報告給哪一個網址。
// 經過report-uri指令指示瀏覽器發送JSON格式的攔截報告到某個url地址
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" } }