ZeroTool Workbench
CSP 头部生成器
通过指令、hash 与 nonce 构建 Content-Security-Policy 头部。含严格模式模板、Report-Only 调试模式以及 Express、Nginx 片段。完全在浏览器中运行。
使用步骤
- 选择一个预设。Strict 对应 OWASP 的「strict CSP」推荐配置,Empty 让你从空白策略开始。
- 切换模式。先用 Report-Only:浏览器只上报违规,不阻断真实用户。
- 逐条指令:点击关键字芯片(
‘self’、‘strict-dynamic’、‘none’)、协议芯片(https:、data:),或在输入框里写主机/路径后按 Enter。 - 用hash 计算器为某段 inline script / style 生成 SHA-256/384/512 哈希;或点击
+ nonce生成一次性 nonce。 - 切换输出页签复制需要的形式:HTTP header、HTML <meta>、Express (helmet)、Nginx
add_header。
Strict CSP 起步配置
Strict 预设围绕三条规则展开:script-src 写 ‘self’ ‘strict-dynamic’,object-src 写 ‘none’,base-uri 写 ‘self’。再配合按请求生成的 nonce 或按脚本计算的 hash,足以拦下绝大多数反射型与存储型 XSS 注入。如果想进一步压制 phishing 类攻击,把 form-action 写成 ‘self’,frame-ancestors 写成 ‘none’。
容易踩的坑
’none’必须独占。 与其他源同列时,浏览器会把整条指令视为无效。frame-ancestors仅在 HTTP 头部生效。 在<meta>里写它会被浏览器忽略,report-uri、report-to、sandbox同理。- hash / nonce 会让
‘unsafe-inline’失效。 现代浏览器会优先采用更安全的策略。 - 务必声明
default-src。 缺失的 fetch 指令会回退到default-src;没有它,未来新增的指令也得不到任何兜底。 - 自定义主机不能包含分号。 分号会终止策略,把后续指令一并破坏。
Hash 还是 Nonce?
对于静态内联内容(埋点片段、关键 CSS、服务端渲染的辅助脚本),用 hash。它和静态 HTML、边缘缓存兼容,不需要每次请求都生成新值。
对于动态渲染内容,用 nonce。服务端在头部里写 ‘nonce-XYZ’,并在所有 <script nonce=“XYZ”> 上盖同一个值。把 nonce 与 ‘strict-dynamic’ 组合使用,可以让被信任脚本的子脚本继承信任,而你不必维护庞大的主机白名单。
部署速查
- Nginx:把 Nginx 页签的内容粘贴到
server块并 reload。always标志让错误响应也带上头部。 - Apache:在
.htaccess或httpd.conf里写Header always set Content-Security-Policy ”…”。 - Express / Node:粘贴 helmet 片段。务必关闭
useDefaults,避免你的策略被 helmet 默认值悄悄合并。 - Cloudflare Pages / Vercel / Netlify:把 HTTP header 写进各自的 headers 配置(
_headers、vercel.json、netlify.toml)。
FAQ
什么是 Content Security Policy?
CSP 是一类 HTTP 响应头部,用于声明浏览器允许加载的脚本、样式、图片、字体、iframe 等内容来源。结合输出编码,它是抵御 XSS、点击劫持与数据注入的最强浏览器侧防线。
上线时应该先用 Enforce 还是 Report-Only?
强烈建议先用 `Content-Security-Policy-Report-Only` 配合 `report-uri`(或 `report-to`)端点。先观察真实流量 1-2 周,把误伤改完,再切到强制生效的 `Content-Security-Policy`。
我必须用 'unsafe-inline' 才能写 inline script / style 吗?
不必。现代 CSP 支持按内容计算的 hash(`'sha256-...'` 等)以及按请求生成的 nonce(`'nonce-...'`),优先使用这两种方式。直接用页面里的 hash 计算器即可。
'strict-dynamic' 起什么作用?
它允许已经被 nonce 或 hash 信任的脚本在运行时再加载其他脚本,而无需一一列出 CDN 主机。这是现代应用推荐的模式,会覆盖基于主机的白名单,从而堵住绕过路径。
生成的头部应该部署到哪里?
请从源站发出 `Content-Security-Policy`(Nginx `add_header`、Apache `Header set`、Cloudflare Transform Rules、Vercel `headers` 等都可以)。HTML `<meta http-equiv>` 仅作为静态托管的兜底;它不支持 `frame-ancestors`、`report-uri`、`report-to`、`sandbox`。