原文: Cordova頁面加載外網圖檔失敗,Refused to load the image 1.使用Cordova頁面加載外網圖檔失敗,抛出異常
Refused to load the image 'http://xxx.png'
because it violates the following Content Security Policy directive: "default-src 'self'
data: gap: https://ssl.gstatic.com 'unsafe-eval'".
Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
錯誤原因:
index.html頁面标頭 的 default-src為self,預設不使用外網資源
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src * ">
解決方案:
在标頭最佳 img-src * 來允許加載外網圖檔
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src * ;img-src *">
2.關于Content-Security-Policy 介紹
官網文檔:
https://www.w3.org/TR/2012/CR-CSP-20121115/Content Security Policy 介紹(轉)
本文介紹的是W3C的
Content Security Policy,簡稱CSP。顧名思義,這個規範與内容安全有關,主要是用來定義頁面可以加載哪些資源,減少XSS的發生。
Chrome擴充已經引入了CSP,通過manifest.json中的content_security_policy字段來定義。一些現代浏覽器也支援通過響應頭來定義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等請求的加載政策。不允許的情況下,浏覽器會模拟一個狀态為400的響應。 |
font-src | font.a.com | 針對Web Font的加載政策。 |
object-src | 針對<object>、<embed>或<applet>等标簽引入的flash等插件的加載政策。 | |
media-src | media.a.com | 針對<audio>或<video>等标簽引入的html多媒體的加載政策。 |
frame-src | 針對frame的加載政策。 | |
sandbox | allow-forms | 對請求的資源啟用sandbox(類似于iframe的sandbox屬性)。 |
report-uri | /report-uri | 告訴浏覽器如果請求的資源不被政策允許時,往哪個位址送出日志資訊。 特别的:如果想讓浏覽器隻彙報日志,不阻止任何内容,可以改用Content-Security-Policy-Report-Only頭。 |
指令值可以由下面這些内容組成:
指令值 | 指令示例 | |
---|---|---|
* | 允許任何内容。 | |
'none' | img-src 'none' | 不允許任何内容。 |
img-src 'self' | 允許來自相同來源的内容(相同的協定、域名和端口)。 | |
data | img-src data | 允許data:協定(如base64編碼的圖檔)。 |
www.a.com | img-src img.a.com | 允許加載指定域名的資源。 |
*.a.com | img-src *.a.com | 允許加載a.com任何子域的資源。 |
https://img.com | img-src | 允許加載img.com的https資源(協定需比對)。 |
https: | img-src https: | 允許加載https資源。 |
'unsafe-inline' | script-src 'unsafe-inline' | 允許加載inline資源(例如常見的style屬性,onclick,inline js和inline css等等)。 |
'unsafe-eval' | script-src 'unsafe-eval' | 允許加載動态js代碼,例如eval()。 |
從上面的介紹可以看到,CSP協定可以控制的内容非常多。而且如果不特别指定'unsafe-inline'時,頁面上所有inline的樣式和腳本都不會執行;不特别指定'unsafe-eval',頁面上不允許使用new Function,setTimeout,eval等方式執行動态代碼。在限制了頁面資源來源之後,被XSS的風險确實小不少。
當然,僅僅依靠CSP來防範XSS是遠遠不夠的,不支援全部浏覽器是它的硬傷。不過,鑒于低廉的開發成本,加上也沒什麼壞處。如果擔心影響面太大,也可以像下面這樣,僅收集不比對規則的日志,先觀察下:
Content-Security-Policy-Report-Only: script-src 'self'; report-uri http://test/
這樣,如果頁面上有inline的JS,依然會執行,隻是浏覽器會向指定位址發送一個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先介紹到這裡。現代浏覽器支援不少與安全有關的響應頭,以後接着再介紹。已經寫完了,
請點這裡繼續浏覽原文連結:
https://imququ.com/post/content-security-policy-reference.html,
參與評論