CSP 头部验证工具
粘贴 Content-Security-Policy 头部的值,一次性验证所有指令和来源值。可检测 unsafe-inline 等高风险设置、缺失的 default-src 兜底、指令名称拼写错误,并以可视化方式展示每个指令允许的来源。
使用技巧
- CSP 通常以 HTTP 响应头的形式下发,但也可以通过
<meta http-equiv="Content-Security-Policy">标签设置(不过 report-uri 等部分指令在 meta 标签中不生效)。 - 在生产环境正式启用 CSP 之前,建议先使用 Content-Security-Policy-Report-Only 头部——它只收集违规报告,方便你在不影响现有功能的前提下评估实际影响。
- 通配符(*)和 'unsafe-inline' 虽然能让开发更省事,但会削弱 CSP 大部分的 XSS 防护能力,上线前务必收紧这类宽松策略。
- 同一指令重复书写两次不会合并取值,只有第一次出现生效。如需追加或覆盖来源,请把所有值写在同一条指令中。
- 浏览器 DevTools 控制台会以红色「Refused to load...」信息显示被拦截的资源,调试过严的 CSP 时应首先查看这里。
常见问题
闲话 ― CSP 为何诞生:仅靠转义从来都无法彻底防住 XSS
Content Security Policy 的构想最早可追溯到 2004 年前后 Robert Hansen 提出的想法,随后从 2008 年左右开始,Mozilla 工程师 Brandon Sterne 主导将其整理成正式规范,最终在 2012 年形成了 W3C 的第一份候选推荐标准(Level 1)。当时跨站脚本攻击(XSS)是网络安全领域最紧迫的问题之一,人们逐渐意识到,仅依赖「开发者认真转义每一处输出」这种做法并不足以构成稳固的防线。CSP 正是作为一种纵深防御机制被设计出来,让浏览器本身来强制限制脚本的合法来源。
CSP Level 2 引入了基于 nonce 和 hash 的内联脚本许可机制,使网站无需依赖 'unsafe-inline' 也能允许特定的内联代码执行。随后 Level 3 又新增了 'strict-dynamic',可以自动信任由已受信脚本动态加载的子脚本,大幅降低了大型网站维护基于主机名白名单的成本。
Google 持续在其自身的大规模服务中推行基于 nonce 的严格 CSP,并据此发布研究成果指出:基于主机名的白名单方式经常可以被绕过,而基于 nonce 或 hash 的策略在实践中有效得多。这一结论目前已被广泛引用为 CSP 的最佳实践,也说明真正关键的设计决策不只是「禁止哪些取值」,而是「从一开始就该基于哪种许可策略来构建」。