WEB安全之XSS注入預防策略——CSP
WEB的盛行讓這個網絡社會更非富,隨之而來的就是安全問題。如果何安全的接受用戶輸入并正確的顯示出來是絕大多部WEB程序的致追求。其中之一就是防止XSS,一般性而言XSS的主要危害主要是:一是頁面可能被惡意或其他原因所定制,二是有可能造成站內數據外泄。
XSS頁面定制
現代WEB內容很多由廠商和用戶共同產生,下面的例子說明一個由廠商和用戶共同產生的數據:
<div class="profile">
<dl>
<dt>$title</dt>
<dd>$description</dd>
</dl>
</div>
其中$title和$description代表了兩個變量,用于輸出一個由用戶產生的標題和內容。以$title為例,如果$title中的內容是:<script>alert(1)</script> 那么運行后輸出到瀏覽器端的內容即為:
<div class="profile">
<dl>
<dt><script>alert(1)</script></dt>
<dd>description</dd>
</dl>
</div>
那么這段代碼的結果只有一種可能:如大家所見會執行這段script,這當然不是開發者所期望的。這個頁面我們就可以理解為被定制了。也許當你拿到了一個HOST可以信任的一個URL,但是很不幸這個URL已經被惡意的傳播者通過XSS所定制,那么也許用戶就可能會相信這個頁面所輸出的內容。那結果是可想而知的。為了預防這種情況。通常情況下WEB開發者會通過escape safe charactor 的方式解決(把 < 變成 < 等)。但是這種預防只停留在通過轉義讓輸出和顯示與輸入一致。
這只是一種解決HTML注入的手段。從安全的角度出發,https://i.xiaomi.com 應該只允許顯示來自 https://i.xiaomi.com 的圖片。同樣的 https;://i.xiaomi.com 也只允許https://land.xiaomi.net 域名下的資源去處理 https://i.xiaom.com上的事務。基于以上的安全限制定下,在現有機制肯定是滿足不了需求了。不過幸好W3C發布了基于該種安全限定的的CSP草案。目前該草案還處于完善階段,這就意味著該草案隨時都有可能被其他規范或草案所替代,當然也有可能放棄。不過IE10以及Webkit已經有對該草案的實現,有了瀏覽器廠商支持,這事就靠譜了。
什么是CSP?
CSP是由單詞 Content Security Policy 的首單詞組成,該草案旨在減少(注意這里是減少而不是消滅哦~)一種內容注入,比如跨站腳本(可能是攻擊哦~親!)。CSP是一種由開發者定義的安全性政策性申明。前面幾句說的太繞人了,說簡單點就是通過CSP所約束的的規責指定可信的內容來源(這里的內容可以指腳本、圖片、iframe、fton、style等等可能的遠程的資源)。通過CSP協定,讓WEB處于一個安全的運行環境中。
如何應用
CSP可以由兩種方式指定:HTTP Header 和HTML。HTTP是在HTTP由增加Header來指定,而HTML級別則由Meta標簽指定。CSP有兩類:Content-Security-Policy 和 Content-Security-Policy-Report-Only。(大小寫無關)
HTTP header :
"Content-Security-Policy:" 策略
"Content-Security-Policy-Report-Only:" 策略
HTTP Content-Security-Policy 頭可以指定一個或多個資源是安全的,而Content-Security-Policy-Report-Only則是允許服務器檢查(非強制)一個策略。多個頭的策略定義由優先采用最先定義的。( 目前Firefox使用x-Content-Security-Policy,WebKit使用X-WebKit-CSP。或許在不久的將來草案最終確定下來之后會統一吧?)
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機制以確保文檔不會被注入惡意的CSP規則。
CSP語法
CSP策略內容由一個 ; 分隔是若干個CSP指令(每條CSP指令的前后空格會被無視掉):
policy = [ directive *( ";" [ directive ] ) ]
每一個CSP由一個 指令名 和 一個可選的指令值 組成
directive = *WSP [ directive-name [ WSP directive-value ] ]
directive-name = 1*( ALPHA / DIGIT / "-" )
directive-value = *( WSP / <VCHAR except ";" and ",">
CSP策略可以是一個指定的URL或是 協議(可選)+HOST+POST(可選)+路徑(可選)的 指令。該指令說明了資源為安全的或非安全的。
示例:
1.只允許本站資源
Content-Security-Policy: default-src ‘self’
2.允許本站的資源以及任意位置的圖片以及trustedscripts.example.com下的腳本。
Content-Security-Policy: default-src ‘self’; img-src *;
script-src trustedscripts.example.com
更多關于CSP的介紹可以參考W3C的相關文檔: https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#content-security-policy-header-field
一部分中文翻譯:http://www.w3.org/html/ig/zh/wiki/CSP
關于CSP的討論
首先CSP的出現肯定可以一定程度上的減少XSS的攻擊(因為攻擊成本提高),但并不一定就意味著CSP普及了XSS攻擊就沒有了
資料:
JPEG網頁圖片病毒 http://baike.baidu.com/view/540655.htm
Shutting Down XSS with Content Sercurity Policy http://blog.mozilla.org/security/2009/06/19/shutting-down-xss-with-content-security-policy/
Content Security Policy ( SCP ) http://developer.chrome.com/extensions/contentSecurityPolicy.html