1. 程式人生 > >CSP(Content Security Policy),在一定程度上能預防XSS攻擊

CSP(Content Security Policy),在一定程度上能預防XSS攻擊

在介紹CSP之前,我們先先來了解一下什麼是XSS攻擊?

XSS攻擊:一種常見的跨指令碼web攻擊方式,它通過向瀏覽器注入一段可執行的惡意指令碼程式碼,並且被瀏覽器成功的執行來達到攻擊的目的。一次XSS攻擊可以獲取到使用者的聯絡方式,向用戶傳送詐騙資訊,甚至可以可以通過SQL注入來攻擊資料庫

XSS攻擊的形成條件:

  1. 向前端注入可執行的惡意程式碼
  2. 程式碼能夠被瀏覽器成功的執行
    為了防止XSS攻擊,要採取很多措施,非常麻煩,就有人提出能不能從根本解決問題,瀏覽器自動禁止外部注入惡意指令碼,這就是CSP的來歷。CSP是在2008年由Mozilla的Sterne提出的瀏覽器安全框架,被設計為一個完整的框架來防禦XSS和CSRF攻擊,通常也可以用來控制app和擴充套件的許可權

一:CSP簡介:

csp實質就是白名單制度,由網頁開發者設定哪些外部資源可以載入、執行,它的實現和執行全部由瀏覽器完成,開發者之需要配置,CSP大大增加了網頁的安全性,攻擊者即使發現了漏洞,也沒辦法注入指令碼,除非還控制了一臺列入白名單的可信主機,他直接在協議層就把一些存在安全隱患的用法預設幹掉了,可以說是把同源策略發揮到了極致(可參考下圖1)

現在我這麼說CSP的問題你可能不太理解,請抱著疑問耐心的往下看一看…

二:CSP的兩種配置方法

1⃣️通過HTTP頭資訊的Content-Security-Policy欄位
2⃣️通過網頁的meta標籤設定
程式碼如下:
<meta
http-equiv="Content-Security-Policy" content="script-src 'self';object-src 'none';style-src cdn.example.org;child-src https">
我來解析一下上述的meta標籤程式碼,CSP是做了如下配置:
script-src:只信任當前域名
object標籤:不信任任何外來URL,即不載入任何資源
style-src: 只信任cdn.example.org third-party.org
child-src: 框架必須使用HTTPS協議載入
一旦啟用之後,不符合CSP的外部資源就會被阻止載入!
當然這只是很小一部分的配置,僅僅配置這些還是不能夠阻止XSS攻擊的

三:詳解CSP的限制選項

3.1 資源載入限制
script-src : 外部指令碼
style-src:樣式表
img-src: 影象
media-src: 媒體檔案(音訊和視訊)
font-src: 字型檔案
object-src: 外掛(eg: flash)
child-src: 框架
frame-ancestors: 嵌入的外部資源,eg: <iframe>標籤
connect-src: HTTP連線(通過XHR 、 WebSockets、EventSource等)
worker-src: worker指令碼
manifest-src: manifest 檔案
3.2 default-src:用來設定上面各個選項的預設值
Content-Security-Policy: default-src ‘self’
3.3 URL限制:
有時,網頁會跟其他網頁產生聯絡,這時也可以加以限制
frame-ancestors:限制嵌入框架的網頁
base-uri:限制<base#href>
form-action:限制<form#action>
3.4 report-uri
有時,我們不僅希望防止XSS,還希望記錄此類行為,report-uri就是用來告訴瀏覽器應該把注入行為報告發送給哪個網址
Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;
    瀏覽器會使用POST方法,傳送一個JSON物件,下面是一個例子
    {
  "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"
  }
}

四:選項值

每個限制選項可以設定以下幾種值,這些值就構成了白名單
主機名:example.org,https://example.com:443
路徑名:example.org/resources/js/
萬用字元:.example.org,://.example.com:(表示任意協議、任意子域名、任意埠)
協議名:https:、data:
關鍵字’self’:當前域名,需要加引號
關鍵字’none’:禁止載入任何外部資源,需要加引號
多個值也可以並列,用空格分隔。

Content-Security-Policy: script-src 'self' https://apis.google.com

如果同一個限制選項使用多次,只有第一次會生效。

# 錯誤的寫法 script-src https://host1.com; script-src https://host2.com 

# 正確的寫法 script-src https://host1.com https://host2.com

如果不設定某個限制選項,就是預設允許任何值。

五、script-src 的特殊值

除了常規值,script-src還可以設定一些特殊值。注意,下面這些值都必須放在單引號裡面。

‘unsafe-inline’:允許執行頁面內嵌的<script>標籤和事件監聽函式
unsafe-eval:允許將字串當作程式碼執行,比如使用eval、setTimeout、setInterval和Function等函式。
nonce值:每次HTTP迴應給出一個授權token,頁面內嵌指令碼必須有這個token,才會執行
hash值:列出允許執行的指令碼程式碼的Hash值,頁面內嵌指令碼的雜湊值只有吻合的情況下,才能執行。

nonce值的例子如下,伺服器傳送網頁的時候,告訴瀏覽器一個隨機生成的token。

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

頁面內嵌指令碼,必須有這個token才能執行。

<script nonce=EDNnf03nceIOfn39fn3e9h3sdfa> // some code </script>

除了script-src選項,nonce值和hash值還可以用在style-src選項,控制頁面內嵌的樣式表。

六、注意點

(1)script-src和object-src是必設的,除非設定了default-src。

因為攻擊者只要能注入指令碼,其他限制都可以規避。而object-src必設是因為 Flash 裡面可以執行外部指令碼。

(2)script-src不能使用unsafe-inline關鍵字(除非伴隨一個nonce值),也不能允許設定data:URL。

下面是兩個惡意攻擊的例子。

<img src="x" onerror="evil()"> <script src="data:text/javascript,evil()"></script>

(3)必須特別注意 JSONP 的回撥函式。

<script src="/path/jsonp?callback=alert(document.domain)//"> </script>

上面的程式碼中,雖然載入的指令碼來自當前域名,但是通過改寫回調函式,攻擊者依然可以執行惡意程式碼。

七:XSS攻擊的其他解決方案

1. 前端在進行校驗的時候,對於特殊字元(eg:<>、'、;)嚴格控制輸入,進行轉義
2.  後端再次對提交的資料進行過濾,如果使用者提交了惡意的資料或攻擊進行遮蔽,但是像部落格園、CSDN這樣大型的IT交流平臺,本身都是需要輸入html標籤的,可以通過白名單進行校驗,允許使用確認安全的標籤,其他都過濾掉
3. 安裝第三方的防火牆,在一定程度上也會阻止xss攻擊,eg: IUEditor,node環境也支援安裝xss

八:總結

其實上述講了很多關於CSP,我們也能瞭解到CSP的優缺點了,在大型叢集上,比如QQ、微博平臺,是不可能使用CSP來進行防禦的,單單成本上來講就是一筆不可想象的鉅款。我認為CSP現在還處於一個理想者狀態,但不能否認未來CSP能夠杜絕XSS攻擊的能力。