CSP 头部生成器

通过指令、hash 与 nonce 构建 Content-Security-Policy 头部。含严格模式模板、Report-Only 调试模式以及 Express、Nginx 片段。在浏览器中运行。

  • 在浏览器中处理
  • 数据不离开你的设备
  • 免费 · 无需注册
重置到预设会恢复该预设的指令和传输开关。Ctrl/⌘+L 清空文本框、计算出的 hash 及反馈,保留当前策略、选项和已保存的策略偏好。
复制当前格式的完整输出。hash 旁的复制只复制计算出的 hash,复制失败后可直接重试。
输出格式 选择 HTTP 头部、HTML meta、Express 或 Nginx。meta 形式会去掉 frame-ancestors、sandbox 和 report-uri,策略警告仍显示在输出下方。
请至少添加一条指令以生成策略。
阅读完整使用指南 CSP 头部生成器:构建严格的内容安全策略,告别繁琐
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。

Strict CSP 起步配置

Strict 预设采用 web.dev 介绍的基于 nonce 的 strict CSP。HTTP header 页签输出:

Content-Security-Policy: default-src 'self'; script-src 'nonce-{RANDOM}' 'strict-dynamic'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests

'nonce-{RANDOM}' 是占位符,不是可用的值。服务器必须在每次响应时把它换成至少 128 位的新随机值,并把同一个值写进它渲染的每个 <script> 的 nonce=”…”。只要策略里还有占位符,工具就会显示警告。不要把一个固定的 nonce 写进静态配置:任何人看到一次就能在注入的脚本里重复使用。

早期版本的这个预设写的是 ‘self’,现在换成了占位符。原因是有 ‘strict-dynamic’ 时,CSP Level 3 会拦截 HTML 解析器插入的所有脚本,除非带有匹配的 nonce 或 hash,并且不再检查 ‘self’ 和主机源(CSP3 §8.2)。所以单独的 script-src ‘self’ ‘strict-dynamic’ 在当前的 Chrome、Firefox、Safari 里一个脚本都不会执行,工具现在会对这种组合给出警告。如果站点是无法设置 nonce 的静态构建,删掉占位符,用 hash 计算器为每段内联脚本加 hash,或者从「适中」预设开始。

Express (helmet) 页签替你完成按响应生成这一步:它加一个中间件,把 crypto.randomBytes(16).toString(‘base64’) 存进 res.locals.cspNonce,并给 script-src 传一个函数,这是 helmet README 里的写法。模板仍要把这个值输出到每个 script 标签上。Nginx 页签保留占位符并加一行注释,因为 Nginx 无法把同一个 nonce 写进应用渲染出的 HTML。

容易踩的坑

  • ’none’ 只能单独使用。 与其他源同列时 ‘none’ 不起作用,其他源照常放行。
  • 有些指令只在 HTTP 头部生效。 CSP3 §3.3 规定 <meta> 里的 frame-ancestors、report-uri、sandbox 无效,也没有 Report-Only 模式。工具会在 <meta> 页签去掉它们并提示。
  • ‘strict-dynamic’ 必须搭配 nonce 或 hash。 没有时页面上的脚本会全部被拦截,工具会提示。
  • 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>` 仅作为静态托管的兜底;CSP Level 3 规定 `<meta>` 里的 `frame-ancestors`、`report-uri`、`sandbox` 无效,工具在该页签中会去掉它们。`report-to` 在 `<meta>` 中仍有效,但它的端点要由 `Reporting-Endpoints` 头部定义。