HelloWorld CSP 配置教程
配置 HelloWorld 的 Content-Security-Policy(CSP)建议先在测试环境用 report-only 观察报表,再逐步收紧规则。默认采用 ‘self’ 限制资源来源,内联脚本用 nonce 或 hash 处理,第三方逐一放行并配合 SRI,生产环境最后强制策略并保持监控。

为什么要为 HelloWorld 配置 CSP?
简单来说,CSP 是浏览器端的一道防线,能有效降低 XSS(跨站脚本)和数据注入风险。对一个示例或真实项目(比如 HelloWorld 应用)配置好 CSP,可以:
- 减少恶意脚本执行的空间
- 帮助发现第三方内容加载问题(通过报告)
- 和 SRI、HSTS 配合时显著提升整体安全性
先搞清楚几个核心概念
1. 策略来源(source list)
像 ‘self’、‘unsafe-inline’、域名(example.com)、协议(https:)等都可以作为来源。优先用 ‘self’,避免使用 ‘unsafe-inline’。
2. Directive(指令)
指令控制不同类型资源的加载,如 default-src、script-src、style-src、img-src 等。未显式指定的资源会退回到 default-src(如果存在)。
3. Nonce 与 Hash
要允许特定内联脚本,推荐使用随机 nonce-*(服务端每次响应生成并内嵌在脚本标签与头部),或使用脚本内容的 sha256-… 哈希来验证。
4. report-only 模式
report-only 是演练模式:浏览器不会阻止资源加载,但会把违规信息发送到指定端点,便于调整策略。
HelloWorld 的最小可行 CSP(从简单到完整)
先给出一个实践中常用的渐进式流程与示例:
- 第一步(观察):在测试环境用 report-only 捕获违规。
- 第二步(迭代):根据报告放行必要源或改造代码避免内联。
- 第三步(生产):启用强制策略并持续监控。
示例 1:测试用(report-only)
HTTP 头部:
Content-Security-Policy-Report-Only: default-src ‘self’; script-src ‘self’ https://cdn.example.com; report-uri /csp-violation-report-endpoint/
示例 2:生产用(启用)
Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘nonce-RANDOM‘ https://cdn.example.com; style-src ‘self’ ‘sha256-abc…’; img-src ‘self’ data:; object-src ‘none’; base-uri ‘self’; frame-ancestors ‘none’; upgrade-insecure-requests;
常用指令速查表
| 指令 | 作用 | 建议 |
| default-src | 默认资源源(回退) | 设为 ‘self’,避免使用通配 * |
| script-src | 脚本来源(含内联 nonce/hash) | 使用 nonce 或 hash,避免 ‘unsafe-inline’ |
| style-src | 样式来源 | 优先用 ‘self’ + hash 或 nonce,允许 cdn 如必要 |
| img-src | 图片来源 | 根据需求允许 data: 或域名 |
| connect-src | AJAX、WebSocket 等 | 明确列出 API 域名与 WebSocket 域 |
| frame-ancestors | 允许被嵌入的父页面域 | 通常设为 ‘none’ 或 ‘self’ |
| report-uri / report-to | 接收违规报告的端点 | 使用 report-only 做调试 |
在常见服务器/框架中的配置示例
Nginx
在 server 或 location 中添加:
add_header Content-Security-Policy “default-src ‘self’; script-src ‘self’ https://cdn.example.com ‘nonce-XYZ’;”;
Apache
在 .htaccess 或 vhost 中:
Header set Content-Security-Policy “default-src ‘self’; img-src ‘self’ data:;”;
Express / Node.js(带 nonce 示例)
思路:服务器在响应前生成随机 nonce 并注入到 HTML 中与头部里:
- 生成:const nonce = crypto.randomBytes(16).toString(‘base64’);
- 设置:res.setHeader(‘Content-Security-Policy’, `script-src ‘self’ ‘nonce-${nonce}’;`);
- 在模板中:<script nonce=”${nonce}”>…</script>
与第三方服务(Analytics、CDN、支付)协同的建议
第三方脚本往往是配置 CSP 的痛点。我通常的处理顺序:
- 优先尝试把第三方脚本放到静态文件并 SRI(如果允许)
- 若必须在线加载,明确放行特定域名;若无法避免内联,尝试用 nonce
- 对不可改造的服务,使用 report-only 收集信息并评估风险
调试技巧与常见问题
- 没有生效?检查是否存在其他 header 覆盖(Nginx/Proxy 常见)或 meta 标签冲突。
- 内联脚本被阻止:优先改为外部脚本并 SRI;若必须内联,使用 nonce 或哈希。
- 报表太多:先在 report-only 聚合,逐条分析,别急着放宽策略。
- 浏览器兼容性:部分老浏览器不支持一些新指令(如 strict-dynamic),要回退到更宽松策略并在现代浏览器上补强。
进阶指令与安全增强
几点可以让 HelloWorld 的 CSP 更加稳健:
- upgrade-insecure-requests:自动把 http 请求提升为 https,减少混合内容问题。
- require-sri-for:要求对外部脚本/样式使用 SRI 校验。
- strict-dynamic:配合 nonce/hash,允许通过信任的脚本动态加载其它脚本,注意兼容性。
如何落地实施(一步步执行清单)
- 1) 在测试环境开启 report-only,记录一周内的违规。
- 2) 按类型(script/style/img/connect)逐条处理违规:尽量替换内联、增加 nonce、或放行可信域名。
- 3) 生成最终策略并在预发布环境强制启用一段时间,注意监控用户影响。
- 4) 生产环境启用并持续收集报告,定期复查第三方依赖。
常见误区(顺便提醒一下)
- 误以为 CSP 能替代服务端过滤:CSP 是客户端防线,不能替代输入校验与输出编码。
- 把 report-only 当成长期方案:那只是调试,不要把它当生产保护。
- 滥用 ‘unsafe-inline’:这是最弱的选择,尽量避免。
好了,按上面的步骤来配置 HelloWorld 的 CSP 大体就能覆盖绝大多数场景。写着写着会发现,CSP 更像是一门折衷艺术:既要严格,又要实际;既要阻断风险,又要兼顾功能。遇到具体问题时,把报表拿出来对照上面的指令表,逐项处理,慢慢就成了套路。