一、CPS簡介
Content-Security-Policy(CSP,內容安全策略)是一種由瀏覽器實施的安全機制,用於防止跨站腳本攻擊(XSS)、數據注入攻擊和點擊劫持等常見 Web 安全威脅。
它通過白名單機制控制網頁可以加載和執行哪些資源,從而有效減少惡意代碼的執行機會。
二、核心作用
1、防止 XSS 攻擊
禁止內聯腳本執行,限制腳本只能從可信域名加載,即使攻擊者注入惡意腳本,也無法執行。
2、控制資源加載來源
可限制圖片、樣式、字體、iframe、Ajax 請求等資源的來源,防止加載惡意內容。
3、防止數據泄露和點擊劫持
通過限制表單提交目標、iframe 嵌入來源等方式,增強頁面行為的安全性。
三、CSP 的設置方式
1、通過 HTTP 響應頭設置(推薦)
示例:
Content-Security-Policy: script-src 'self'; object-src 'none'; img-src * data:;
含義:
-
只允許加載當前域名的腳本;
-
禁止加載任何
<object>標籤資源; -
圖片可從任意來源加載,包括 data URI。
四、配置説明
1、常用指令(Directive)説明
| 指令 | 功能 |
|---|---|
default-src |
默認資源加載策略(其他未指定指令的 fallback) |
script-src |
控制 JavaScript 的來源 |
style-src |
控制 CSS 的來源 |
img-src |
控制圖片的來源 |
connect-src |
控制 Ajax、WebSocket 等連接的目標 |
frame-src |
控制 iframe 的來源 |
form-action |
限制表單提交的目標地址 |
report-uri / report-to |
設置違規報告接收地址,用於安全監控 |
2、指令值(Source)説明
| 值 | 含義 |
|---|---|
'self' |
只允許同源資源 |
'none' |
禁止任何資源 |
'unsafe-inline' |
允許內聯腳本/樣式(⚠️降低安全性) |
'unsafe-eval' |
允許使用 eval() 等動態執行代碼(⚠️高風險) |
https://example.com |
允許指定域名 |
nonce-<隨機值> |
僅允許帶有匹配 nonce 屬性的腳本 |
sha256-<哈希值> |
僅允許哈希匹配的內聯腳本 |
五、注意事項
1、生產前必做,僅報告模式
先在 Content-Security-Policy-Report-Only 頭裏跑 1-3 天,只記錄不阻斷:
nginx配置如下:
add_header Content-Security-Policy-Report-Only
"default-src 'self'; script-src 'self' https://static.xxx.com; report-uri /csp-report" always;
觀察 /csp-report 接收到的 JSON 違規日誌,確認無合法資源被誤殺後,再改成正式的 Content-Security-Policy 頭 。
2、script-src 沒有nonce/hash 不能使用 'unsafe-inline'
否則會導致所有內聯 <script>alert(1)</script> 和 DOM 級 element.onclick = ... 放行。
攻擊示例:
#請求
https://victim.com/search?q=
alert(document.cookie)
#返回結果
搜索關鍵詞:alert(document.cookie)
錯誤配置示例:
add_header Content-Security-Policy "
default-src 'self';
script-src 'self' data:;
3、script-src 不能允許 data
否則會導致 data:text/javascript,alert(1) 這種 Base64 內嵌腳本會被執行。
攻擊者只需注入 <script src="data:text/javascript,..."> 即可完成 XSS,完全繞過域名白名單。
錯誤配置示例:
add_header Content-Security-Policy "
default-src 'self';
script-src 'self' 'unsafe-inline';
六、服務器配置示例
1、NGINX配置示例
在 server {} 塊里加一行:
server {
listen 80;
server_name example.com;
# 全部響應都附加 CSP
add_header Content-Security-Policy "
default-src 'self' localhost:443 'unsafe-inline' 'unsafe-eval' blob: data: ;
sscript-src 'self' 'unsafe-inline' 'unsafe-eval';;
style-src 'self' https://fonts.googleapis.com;
img-src 'self' data: https:;
font-src 'self' https://fonts.gstatic.com;
object-src 'none';
frame-ancestors 'self';
upgrade-insecure-requests;
" always;
location / {
proxy_pass http://127.0.0.1:8080;
# 其他代理頭省略
}
}
重啓 Nginx 後,所有 HTML 響應都會帶上該頭字段 。
2、Tomcat配置示例
修改 conf/web.xml,追加全局過濾器:
HttpHeaderSecurityFilter
org.apache.catalina.filters.HttpHeaderSecurityFilter
content-security-policy
default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
object-src 'none';
frame-ancestors 'self';
HttpHeaderSecurityFilter
/*
重啓 Tomcat 後,所有響應自動攜帶 CSP 頭
3、Spring Boot 示例
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp.policyDirectives(
"default-src 'self'; " +
"script-src 'self' https://cdn.jsdelivr.net; " +
"style-src 'self' https://fonts.googleapis.com; " +
"img-src 'self' data: https:; " +
"font-src 'self' https://fonts.gstatic.com; " +
"object-src 'none'; " +
"frame-ancestors 'self'; " +
"upgrade-insecure-requests;")));
return http.build();
}
}
Spring Boot 3.x 可用,啓動後觀察響應頭已含 Content-Security-Policy
原文鏈接:https://www.cnblogs.com/ljbguanli/p/19113503