Content Security Policy (CSP) 是一種電腦安全標準,旨在防禦跨站指令碼 (XSS)、資源數據盜取 (XSD) 和網頁樣式置換等代碼注入攻擊,阻止惡意內容在受到信任的網頁環境中執行。CSP 透過在 HTTP 標頭中添加指令,限制瀏覽器載入和執行特定來源的資源,這些資源可能是 JavaScript、CSS、字體、圖像、影片或任何嵌入的內容。
常見用途
請參考簡單聊聊 XSS 攻擊及防制這篇所給出的具體案例,但假如今天我有設定以下 CSP:
1 | Content-Security-Policy: default-src 'self'; |
那就代表著我只允許我本身網站的 JS 進行載入,就可以抵禦 XSS 攻擊。
但注意一點,如果 CSP 過度嚴格,可能會導致網站功能受到限制,甚至無法正常運作。例如,如果 CSP 禁止載入任何外部資源,那麼網站就無法使用第三方 JavaScript 或 CSS 庫。
繞過手法及防制手段
如果 CSP 那麼強大到可以抵禦外部 JS 載入,那今天我們只要換個想法讓我們進行攻擊的腳本偽造成內部載入不就好了嗎OwO
所以今天假設我們今天注入了一個 JS 片段如下:
1 | <script src="data:text/javascript;base64,YWxlcnQoIlJpY2tSb2xsIFlFRUVFRUUiKTs="></script> |
他其實就是把 alert("RickRoll YEEEEEE");
轉成 Base64 後,可以偽造成伺服器本身發出的 JS,但我們也可以利用
1 | Content-Security-Policy: default-src 'self'; script-src 'self' |
來去禁止使用 inline scripts 和 eval()。這樣,像例子中的 Base64 編碼腳本將會被阻止執行,但如果你今天網頁中同樣有使用到 <script>
嵌入的話怎麼辦?
所以我們也可以考慮使用 nonce(number used once)或 hash 來允許特定的腳本。例如今天你必須內嵌一個腳本,可以幫他加個 nonce 属性,然後再 CSP 規則中加上這個 nonce:
1 | <script nonce="randomNonceValue">alert('Hello World');</script> |
1 | Content-Security-Policy: script-src 'nonce-randomNonceValue' |
這樣就可以只載入你同意的 Script 了,萬歲!
CSP 規則跟語法
1 | Content-Security-Policy: default-src 'self'; script-src 'self' https://example.com; img-src 'self' https://img.example.com; style-src 'self' 'unsafe-inline'; |
含義如下:
default-src 'self'
:預設允許加載來自同一來源的資源script-src 'self' https://example.com
:允許加載來自同一來源以及 https://example.com 的 JSimg-src 'self' https://img.example.com
:允許加載來自同一來源以及 https://img.example.com 的圖片style-src 'self' 'unsafe-inline'
:允許加載來自同一來源的 CSS,並允許 inline-style
Reference
Content Security Policy Cheat Sheet
Mozilla - Content-Security-Policy