Chrome擴展已經(jīng)引入了CSP,通過manifest.json中的content_security_policy字段來定義。一些現(xiàn)代瀏覽器也支持通過響應頭來定義CSP。下面我們主要介紹如何通過響應頭來使用CSP,Chrome擴展中CSP的使用可以參考Chrome官方文檔。
早期的Chrome是通過X-WebKit-CSP響應頭來支持CSP的,而firefox和IE則支持X-Content-Security-Policy,Chrome25和Firefox23開始支持標準的的Content-Security-Policy,見下表。
響應頭 | Chrome | Firefox | Safari | IE |
---|---|---|---|---|
Content-Security-Policy | 25+ | 23+ | - | - |
X-Content-Security-Policy | - | 4.0+ | - | 10.0(有限的) |
X-Webkit-CSP | 14+ | - | 6+ | - |
完整的瀏覽器CSP支持情況請移步CanIUse。
要使用CSP,只需要服務端輸出類似這樣的響應頭就行了:
Content-Security-Policy: default-src 'self' |
default-src是CSP指令,多個指令之間用英文分號分割;'self'是指令值,多個指令值用英文空格分割。目前,有這些CSP指令:
指令 | 指令值示例 | 說明 |
---|---|---|
default-src | 'self' cnd.a.com | 定義針對所有類型(js、image、css、web font,ajax請求,iframe,多媒體等)資源的默認加載策略,某類型資源如果沒有單獨定義策略,就使用默認的。 |
script-src | 'self' js.a.com | 定義針對JavaScript的加載策略。 |
style-src | 'self' css.a.com | 定義針對樣式的加載策略。 |
img-src | 'self' img.a.com | 定義針對圖片的加載策略。 |
connect-src | 'self' | 針對Ajax、WebSocket等請求的加載策略。不允許的情況下,瀏覽器會模擬一個狀態(tài)為400的響應。 |
font-src | font.a.com | 針對Web Font的加載策略。 |
object-src | 'self' | 針對<object>、<embed>或<applet>等標簽引入的flash等插件的加載策略。 |
media-src | media.a.com | 針對<audio>或<video>等標簽引入的html多媒體的加載策略。 |
frame-src | 'self' | 針對frame的加載策略。 |
sandbox | allow-forms | 對請求的資源啟用sandbox(類似于iframe的sandbox屬性)。 |
report-uri | /report-uri | 告訴瀏覽器如果請求的資源不被策略允許時,往哪個地址提交日志信息。 特別的:如果只想讓瀏覽器匯報日志,而不阻止任何內容??梢愿挠肅ontent-Security-Policy-Report-Only響應頭。 |
指令值可以由下面這些內容組成:
指令值 | 指令示例 | 說明 |
---|---|---|
* | img-src * | 允許任何內容。 |
'none' | img-src 'none' | 不允許任何內容。 |
'self' | img-src 'self' | 允許來自相同來源的內容(相同的協(xié)議、域名和端口)。 |
data | img-src data | 允許data:協(xié)議(例如base64編碼的圖片)。 |
www.a.com | img-src img.a.com | 允許加載指定域名的資源。 |
*.a.com | img-src *.a.com | 允許加載a.com任何子域的資源。 |
https://img.com | img-src https://img.com | 允許加載img.com的https資源(協(xié)議需匹配)。 |
https: | img-src https: | 允許加載https資源。 |
'unsafe-inline' | script-src 'unsafe-inline' | 允許加載inline資源(例如常見的style屬性,onclick,inline js和inline css等等)。 |
'unsafe-eval' | script-src 'unsafe-eval' | 允許加載動態(tài)js代碼,例如eval()。 |
從上面的介紹可以看到,CSP協(xié)議可以控制的內容非常多。而且如果不特別指定'unsafe-inline'時,頁面上所有inline的樣式和腳本都不會執(zhí)行;不特別指定'unsafe-eval',頁面上不允許使用new Function,setTimeout,eval等方式執(zhí)行動態(tài)代碼。在限制了頁面資源來源之后,被XSS的風險確實小不少。
當然,僅僅依靠CSP來防范XSS是遠遠不夠的,不支持全部瀏覽器是它的硬傷。不過,鑒于低廉的開發(fā)成本,加上也沒什么壞處。如果擔心影響面太大,也可以像下面這樣,僅收集不匹配規(guī)則的日志,先觀察下:
Content-Security-Policy-Report-Only: script-src 'self' ; report-uri http: //test/ |
這樣,如果頁面上有inline的JS,依然會執(zhí)行,只是瀏覽器會向指定地址發(fā)送一個post請求,包含這樣的信息:
{ "csp-report" :{ "document-uri" : "http://test/test.php" , "referrer" : "" , "violated-directive" : "script-src 'self'" , "original-policy" : "script-src 'self'; report-uri http://test/" , "blocked-uri" : "" }} |
CSP先介紹到這里。現(xiàn)代瀏覽器支持不少與安全有關的響應頭,以后接著再介紹。