CSP
CSP
这篇笔记还在编辑中,内容可能会继续补充、调整或重写。
CSP 的位置
Content Security Policy 通过 HTTP 响应头限制页面可以执行或加载的资源,是 XSS 的纵深防御。它不能替代按上下文编码、安全 DOM API、输入校验和依赖治理;错误策略也可能被页面中的脚本 gadget 绕过。
严格 CSP
只维护大量域名白名单的策略容易随着第三方服务膨胀,也可能信任托管用户内容的宽泛来源。现代严格 CSP 主要为允许执行的脚本分配每次响应唯一的 nonce,或为固定脚本声明 hash:
Content-Security-Policy:
default-src 'self';
script-src 'nonce-{RANDOM}' 'strict-dynamic';
object-src 'none';
base-uri 'none';
frame-ancestors 'none';
report-to csp-endpoint
nonce 必须由服务端为每个响应使用密码学安全随机数生成,并同时写入策略和允许的 <script>。不能使用固定 nonce、构建时常量或用户可控值。
从报告模式迁移
- 盘点内联脚本、动态脚本、Worker、连接和第三方资源。
- 先发送
Content-Security-Policy-Report-Only收集违规。 - 对报告去重,并区分扩展、注入噪声和真实应用调用。
- 清理危险写法,加入 nonce/hash,再对小流量强制执行。
- 观察业务成功率和 CSP 违规,逐步扩大范围。
Report-Only 不提供阻止效果,不能长期被当作已经启用 CSP。
与其他策略组合
frame-ancestors控制页面能否被嵌入,优先于旧式点击劫持头object-src 'none'和base-uri 'none'收紧高风险能力- Trusted Types 限制字符串进入 DOM XSS Sink
- SRI 可以验证跨源静态资源完整性,但要设计更新流程
样式、图片、字体和 API 的指令也应遵循最小权限,但不要为了消除报告就随意加入 *、unsafe-inline 或宽泛域名。
实践验收
- 策略通过 HTTP 响应头发送,而不只依赖 Meta 标签
- nonce 每个响应唯一且不可预测
- 应用不依赖
unsafe-eval和无边界unsafe-inline - Report-Only 报告经过归类,强制策略已在真实流量验证
- CSP 违规能关联页面、版本和具体指令
- 修改第三方脚本或框架配置后有回归检查