Content-Security-Policy 為瀏覽器目前所實作的一個標準, 主要是用在防禦 XSS 攻擊的標準.((當然不可能完全防禦…
簡單解釋:利用 http header 去定義在 html 限制載入的跨站 script (例如 img-src, script-src…等可以載入外部資源的標籤).
Content-Security-Policy 普及的標準為 1.0 版本
Content-Security-Policy level2 (增加了進階的 inline script 執行限制,child-src…等等,請參考MDN介紹)
Content-Security-Policy level3: 撰寫本文時還在草案中…
以下將 Content-Security-Policy 簡稱 CSP
接下來簡單介紹 CSP 1.0 的幾個常見用法
比如我們可以新增一個 test.php 檔案加上標頭(這邊是為了 demo 方便,通常是會設在 webserver 上)
header("Content-Security-Policy: default-src 'self'"); print "<h1>CSP demo</h1> <script src='https://code.jquery.com/jquery-3.2.1.slim.min.js'></script> <iframe src='https://www.w3schools.com'></iframe> <img src='https://www.w3schools.com/tags/smiley.gif'> <script>alert('test');</script>";
試著執行看看:
打開 F12 (開發者工具)可以發現 CSP 將非來自本身 domain 的資源都阻擋下來.(default-src: ‘self’)
而且預設 CSP 是會阻擋 inline 程式碼, eval 函式及 inline CSS 的,避免攻擊者惡意注入程式碼.
再來看另一個設定範例
- default-src: 設為僅允許本身 domain
- img-src: 僅允許 https 協定及本身來源.
- frame-src: 僅允許來自 www.w3schools.com 及本身來源.
- script-src: 允許 inline script.
header("Content-Security-Policy: default-src 'self';img-src https: 'self'; frame-src 'self' www.w3schools.com;script-src 'unsafe-inline'"); print "<h1>CSP demo</h1> <script src='https://code.jquery.com/jquery-3.2.1.slim.min.js'></script> <iframe src='https://www.w3schools.com'></iframe> <img src='https://www.w3schools.com/tags/smiley.gif'> <script>alert('test');</script>";
可以看到上面這個範例僅外部 script 仍被 CSP 阻擋(因 default-src 只允許本身來源):
所有的 CSP 規則都是遵循這樣的一個設定, 以下就不 demo 範例 來介紹幾個比較常用的設定吧!
directives (在 header 中 directives 與後面的規則相隔空白,directives 之間以分號做分隔 ) :
例如:script-src ‘self’ www.camel2243.com ‘unsafe-inline’;img-src ‘self’ https:;
- default-src ‘self’ (僅載入置身來源,預設會套用至其他的未設定的 CSP rule)
- script-src ‘self’ ‘unsafe-eval’ ‘unsafe-inline’ (載入自身來源的 script,並允許 eval 函式及 inline script)
- img-src ‘self’ https: data: (載入自身來源, data url及 https 協定的圖片位址)
- frame-src ‘none’ (不載入任何 iframe src)
- style-src ‘self’ (載入自身來源的外部資源)
- font-src ‘self’ (css font-face 僅載入自身來源的字型)
ps. 在 CSP level2 又加上了如:child-src 等等的 directives, 去限制 web worker 或動態插入的程式碼限制等.(只是瀏覽器支援不是這麼普及就是)
參考資料:
http://devco.re/blog/2014/04/08/security-issues-of-http-headers-2-content-security-policy/