跳转到主要内容

CSP

本文约需 2 分钟阅读

CSP (Content Security Policy) 是一种通过 HTTP 响应头声明允许在网页上执行的资源来源的安全机制。作为大幅降低跨站脚本 (XSS)危害的防御层,它于 2012 年在 W3C 标准化。服务器向浏览器指示「本页面只允许执行该域名的脚本」,从而在浏览器层面阻止攻击者注入的恶意脚本执行。

作为 XSS 对策的定位

XSS 对策的基础是输入的净化和输出的转义,但这些对策容易因开发者的失误而出现疏漏。 CSP 作为补充这些对策的「最后一道防线」发挥作用。即便因转义疏漏使攻击代码混入 HTML,只要 CSP 设置正确,浏览器就会拒绝执行该脚本。将安全编码与 CSP 结合,即可实现纵深防御。

主要指令

指令控制对象设置示例
default-src其他指令的回退'self'
script-srcJavaScript 的加载与执行'self' 'nonce-abc123'
style-srcCSS 的加载与应用'self' 'unsafe-inline'
img-src图像的加载源'self' data: https://cdn.example.com
connect-srcfetch / XHR / WebSocket 的连接目标'self' https://api.example.com
frame-ancestors允许以 iframe 嵌入的来源'none'
form-action表单的提交目标'self'

基于 nonce 与基于 hash 的许可方式

允许内联脚本的方法有 nonce 方式和 hash 方式两种。

nonce 方式

服务器为每个请求生成一个随机值 (nonce),并在 CSP 头和 script 标签中嵌入相同的值。只有值一致的脚本才会被执行。它适合动态页面,且 Next.js、Rails 等框架支持自动生成 nonce。

hash 方式

从内联脚本的内容计算出 SHA-256 等哈希值,并写入 CSP 头。脚本内容哪怕变动一个字节,哈希就会不匹配而无法执行。它适合静态脚本,但每次更改内容都需要重新计算哈希。

通过 report-uri / report-to 进行监控

CSP 内置了向服务器报告策略违规的机制。report-uri (旧规范) 或 report-to (新规范) 指令指定报告发送目标后,浏览器每次检测到策略违规都会发送 JSON 格式的报告。首先使用 Content-Security-Policy-Report-Only 头仅收集报告,确认不会破坏现有功能后再迁移到生产环境应用,这才是安全的导入步骤。

CSP 导入流程

用 Report-Only 掌握现状分析违规报告分阶段收紧策略用 nonce / hash 管理例外切换到生产环境头持续监控报告

导入时的常见失误

草率地许可 unsafe-inline

因为内联脚本无法运行就添加 'unsafe-inline',会使 CSP 的 XSS 防御效果几乎失效。迁移到 nonce 方式才是正解。

滥用通配符

在 script-src 中指定 * 会导致可从任意域名加载脚本。应逐个列举允许的域名。

遗漏对第三方的考虑

若忘记广告、分析、聊天小部件等第三方脚本,会导致生产环境中功能停止。

CSP 是与WAFSSL/TLS并列的 Web 安全基础技术。Web 安全相关书籍 (Amazon)推荐据此进行系统性学习。也请一并参阅浏览器扩展的安全性浏览器密码的安全性以及初创公司安全检查清单

相关术语

这篇文章对您有帮助吗?

XHatena