CSP的出現可以一定程度的減少XSS的攻擊,但不一定意味著XSS的消失。
CSP是可以在一定程度上提高XSS的攻擊難度的,甚至杜絕XSS,則是CSP策略用的好。還要考慮CSP是否能夠充分利用,因為CSP在提供安全性的同時也提高了前端邏輯的複雜性度,很多資源需要調整,類似QQ,新浪微博,搜狐這樣的站群,想通過適當的CSP同時提高安全性和易用性是很難的。
1 2 3 4 5 |
Example: //只允許本站資源文件 Content-Security-Policy: default-src 'self' //允许本站的资源以及任意位置的图片以及https://neverj.com下的資源文件 Content-Security-Policy: default-src 'self'; img-src *; script-src http://neverj.com; |
CSP主要從協議層把一些存在安全隱患的用法替換給幹掉
設定重點:
- CSP策略在默认的情况下是不允许使用data URIs资源的,如果要使用,那么需要显示的指定,比如:img-src ‘self’ data;
- script-src:在處理腳本資源的時候設置“ unsafe-inline”可以阻止內聯Jss的執行。使用unsafe-eval開關可以禁止eval,setTimeout,setInterval函數的執行。某些Browser如要播放串流影片也要加放 blob:。
- object-src:控制嵌入,代碼,存檔applet等對象。
- style-src:會控製樣式表@import和rel時所保留的URI資源,設置不安全的內聯規則可以是瀏覽器拒絕解析內部樣式和內聯樣式定義。並且不會阻止鏈入外部樣式表。
- img-src:可以控製圖片資源的連接,包括img標籤的src屬性,以及CSS3中的url()和image()方法,以及鏈接標籤中的href屬性(當rel設置成與圖像相關的值, HTML支持的圖標)
- media-src:控制媒體類型的外部鏈入資源,例如視頻,音頻,源和和軌道標籤的src屬性。
- frame-src:控制內嵌框架包含的外部頁面連接:iframe或框架。
- font-src:控制CSS中的@font-face
- connect-src:控制XMLHttpRequest中的open(),WebSocket,EventSource
- child-src:框架
- frame-ancestors:插入的外部資源(例如<frame>,<iframe>,<embed>和<applet>)
- worker-src:worker脚本
- manifest-src:manifest 文件
- default-src:設置了上面各個選項的預設值
而啟用CSP有兩種方法,Server side set header 跟 HTML meta tag。
Server side set header
1 2 3 4 5 6 |
Content-Security-Policy: script-src 'self'; object-src 'none'; style-src https://www.neverj.com http://www.hkitlife.com www.letgoaltech.com; child-src https:; ... |
HTML meta tag
1 |
<meta http-equiv ="Content-Security-Policy" content ="script-src 'self'; object-src'none'; style-src https://www.neverj.com http://www.hkitlife.com www.letgoaltech.com; child-src https:;" > |
上面的代碼中,CSP做瞭如下配置。
腳本:只信任當前域名<object>
標籤:不信任任何URL,即不加載任何資源
CSS:只信任https://www.neverj.com http://www.hkitlife.com www.letgoaltech.com
框架(frame): 必須使用HTTPS協議加載
其他資源:沒有限制
启用后,不符合 CSP 的外部资源就会被阻止加载。
default-src:
1 |
Content-Security-Policy: default-src 'self' |
如果同時設置某個單項限制(例如font-src)和default-src,前者會覆蓋外殼,即字體文件會採用font-src的值 ,其他資源依然採用default-src的值。
script-src的特殊值
除了常規值,script-src還可以設置一些特殊值。注意,下面這些值都必須放在單引號裡面。
unsafe-inline:允許執行頁面內嵌的script標籤和事件監聽函數
unsafe-eval:允許將字符串視為代碼執行,某種使用eval,setTimeout,setInterval和Function等函數
nonce值:每次HTTP響應都會授予一個令牌,頁面內嵌腳本必須有這個令牌,才會執行
hash值:列出允許執行的腳本代碼的哈希值,頁面內嵌腳本的哈希值只有吻合的情況下,才能執行
1 2 3 4 |
//nonce值的示例如下,服務器發送網頁的時候,告訴瀏覽器一個隨機生成的令牌。 Content-Security-Policy: script-src 'nonce-EBcje05nceNJfn39fn3e9h3jlif' //頁面內嵌腳本,必須有這個令牌才能執行。 <script nonce=EBcje05nceNJfn39fn3e9h3jlif> // some code </script> |
1 2 3 4 5 |
//hash值的示例如下,服務器定義一個允許執行代碼的hash值。 Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng=' //下面的代碼就會允許執行,因為hash值相符。 <script>alert('Hello, world.');</script> //注意,計算hash值的時候,<script>標籤不算在內。 |
除了script-src選項,nonce值和hash值還可以用在style-src選項,控制頁面內嵌的樣式表。
日常注意
- script-src和object-src是必設的,除非設置了default-src。因為攻擊者只要能注入腳本,其他限制都可以規避。而object-src必設是因為Flash裡面可以執行外部腳本。
- script-src無法使用unsafe-inline關鍵字(除非伴隨一個nonce值),也不能允許設置data:URL。
下面是两个恶意攻击的例子。
1<img src="x" onerror="evil()"> <script src="data:text/javascript,evil()"></script> - 必须特别注意 JSONP 的回调函数。
1<script src="/path/jsonp?callback=alert(document.domain)//"> </script>
上面的代碼中,雖然加載的腳本來自當前域名,但是通過改寫重寫函數,攻擊者依然可以執行惡意代碼。