WEB應用內容安全策略(Content Security Policy)

玉鴦發表於2019-02-20

CSP

內容安全策略(Content Security Policy)是什麼?

  內容安全策略(Content Security Policy)簡稱CSP是由W3C小組定義的一項規範,其主要作用是提供一個額外的安全層,用於檢測並削弱某些特定型別的攻擊,包括跨站指令碼 (XSS) 和資料注入攻擊等.

  目前內容安全策略(Content Security Policy)的規範一共有三個版本:

  1. Content Security Policy Level 1
  2. Content Security Policy Level 2
  3. Content Security Policy Level 3

  現在主要使用的是第二個版本,第三個版本目前還在草案當中

CSP的作用

  CSP被設計出來的目的就是為了效防範內容注入攻擊,如XSS攻擊等.

  它通過讓開發者對自己WEB應用宣告一個外部資源載入的白名單,使得客戶端在執行WEB應用時對外部資源的載入做出篩選和識別,只載入被允許的網站資源.對於不被允許的網站資源不予載入和執行.同時,還可以將WEB應用中出現的不被允許的資源連結和詳情報告給我們指定的網址.如此,大大增強了WEB應用的安全性.使得攻擊者即使發現了漏洞,也沒法注入指令碼,除非還控制了一臺列入了白名單的伺服器.

使用CSP

CSP的選擇

  根據W3C的設計,CSP分為兩種模式:

  • 一種是Content-Security-Policy.

使用這種模式,將會直接阻止非法的外部資源載入,同時也可以選擇是否配置將非法資源載入的連結和行為報告給我們指定的網址

  • 另一種是Content-Security-Policy-Report-Only

使用這種模式時,客戶端在遇到非法的外部資源載入時並不會阻止,而是正常載入.但是會將次載入行為和連結報告給我我指定的網址.所以使用此模式時,必須要使用report-uri策略配置報告非法資源載入情況的網址.

  以上是CSP策略的兩種模式,在實際使用中,我們可以根據自己的情況任意選擇其中一種模式.

CSP的使用方式

  CSP的使用方式有兩種:

  • 一種是前端開發時直接在HTML頁面中使用<meta>標籤,如下:
<meta http-equiv="Content-Security-Policy" content="default-src 'self';">

<!-- or -->

<meta http-equiv="content-security-policy-report-only" content="default-src 'self';">
複製程式碼
  • 一種是後端開發或服務運維人員對頁面的HTTP請求的響應配置Content-Security-Policy屬性,如在NGINX伺服器上配置如下
add_header  Content-Security-Policy  "default-src 'self'";

# or

add_header  Content-Security-Policy-Report-Only  "default-src 'self'";
複製程式碼

  通過以上兩種方式的任意一種即可啟用CSP.

CSP的配置

  一個策略由一系列策略指令所組成,每個策略指令都描述了一個針對某個特定型別資源以及生效範圍的策略。你的策略應當包含一個default-src策略指令,在其他資源型別沒有符合自己的策略時應用該策略(有關完整列表檢視default-src)。一個策略可以包含default-src或者script-src指令來防止內聯指令碼執行, 並杜絕eval()的使用。 一個策略也可包含一個default-srcstyle-src指令去限制來自一個<style>元素或者style屬性的內聯樣式。

  示例: 常見用例,來自MDN:

  1. 一個網站管理者想要所有內容均來自站點的同一個源 (不包括其子域名)
Content-Security-Policy: default-src 'self'
複製程式碼
  1. 一個網站管理者允許內容來自信任的域名及其子域名 (域名不必須與CSP設定所在的域名相同)
Content-Security-Policy: default-src 'self' *.trusted.com
複製程式碼
  1. 一個網站管理者允許網頁應用的使用者在他們自己的內容中包含來自任何源的圖片, 但是限制音訊或視訊需從信任的資源提供者(獲得),所有指令碼必須從特定主機伺服器獲取可信的程式碼.
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
複製程式碼

  在這裡,各種內容預設僅允許從文件所在的源獲取, 但存在如下例外:

  • 圖片可以從任何地方載入(注意 "*" 萬用字元)。
  • 多媒體檔案僅允許從 media1.commedia2.com 載入(不允許從這些站點的子域名)。
  • 可執行指令碼僅允許來自於 userscripts.example.com
  1. 一個線上銀行網站的管理者想要確保網站的所有內容都要通過SSL方式獲取,以避免攻擊者竊聽使用者發出的請求。
Content-Security-Policy: default-src https://onlinebanking.jumbobank.com
複製程式碼

  該伺服器僅允許通過HTTPS方式並僅從onlinebanking.jumbobank.com域名來訪問文件。

  1. 一個線上郵箱的管理者想要允許在郵件裡包含HTML,同樣圖片允許從任何地方載入,但不允許JavaScript或者其他潛在的危險內容(從任意位置載入)。
Content-Security-Policy: default-src 'self' *.mailsite.com; img-src *
複製程式碼

  注意這個示例並未指定script-src。在此CSP示例中,站點通過default-src指令的對其進行配置,這也同樣意味著指令碼檔案僅允許從原始伺服器獲取

  1. 違例報告樣本

  預設情況下,違規報告並不會傳送。為啟用傳送違規報告,你需要指定report-uri策略指令,並提供至少一個URI地址去遞交報告。這個地址可以是相對於當前網站的相對地址,也可以是一個絕對地址:

Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports
複製程式碼

  報告格式如下:

{
  "csp-report": {
    "document-uri": "http://example.com/signup.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
  }
}
複製程式碼

  違例報告的語法:

作為報告的JSON物件報告包含了以下資料:

  • document-uri: 發生違規的文件的URI。
  • referrer: 違規發生處的文件引用(地址)。
  • blocked-uri: 被CSP阻止的資源URI。如果被阻止的URI來自不同的源而非文件URI,那麼被阻止的資源URI會被刪減,僅保留協議,主機和埠號。
  • violated-directive: 違反的策略名稱。
  • original-policy: 在 Content-Security-Policy HTTP 頭部中指明的原始策略。

CSP的策略指令

  • 常見策略型別
策略指令 策略說明
default-src 預設載入策略
script-src 外部指令碼
style-src 樣式表
img-src 影象
media-src 媒體檔案(音訊和視訊)
font-src 字型檔案
object-src 外掛(比如 Flash)
child-src 框架
frame-ancestors 嵌入的外部資源(比如<iframe><iframe><embed><applet>
connect-src HTTP 連線(通過 XHR、WebSockets、EventSource等)
worker-src worker指令碼
manifest-src manifest 檔案

想要了解策略的全部型別可以檢視這裡

  • 策略值型別
指令值 指令值說明
* 允許任何內容
‘none’ 不允許任何內容
‘self’ 允許來自相同來源的內容(相同的協議、域名和埠)
data: 允許 data: 協議(如 base64 編碼的圖片)
www.Google.com 允許載入指定域名的資源
*.Google.com 允許載入 Google.com 任何子域的資源
‘unsafe-inline’ 允許使用內聯資源,如內聯的 <script> 元素、javascript: URL、內聯的事件處理函式和內聯的 <style> 元素.兩側單引號是必須的.
‘unsafe-eval’ 允許使用eval()等通過字串建立程式碼的方法。兩側單引號是必須的。

瀏覽器相容性

Content Security Policy Level 1

CSP1

Content Security Policy Level 2

CSP2

上面是我的一些粗淺的總結,希望對大家有所幫助.如果文中有何不當之處請予以斧正,謝謝.

參考資料:

我的個人網址: www.wangyiming19950222.com

相關文章