安全响应头不是安全代码的替代品,但它们让浏览器强制实施有用的边界。策略应描述实际被服务的页面,而不是从另一个项目复制来的泛型模板。

HTML、本地样式表与 favicon 决定 CSP 资源许可。Content-Security-Policy 强制执行;Report-Only 揭示违规且报告需另行配置。CSP 应通过响应头发送:frame-ancestors 在 meta 中被忽略且不回退到 default-src,form-action 需要自己的指令,style-src self 本身不允许内联样式。HSTS 从有效 HTTPS 响应学习;www.example.test 的 includeSubDomains 覆盖该主机与后代,不覆盖 example.test 或 api.example.test。应检查正常页、缺失页与资源响应,并在真实浏览器验证执行。本图不声称已经测试。
把响应头视为部署契约:匹配实际资源,区分强制执行与仅报告策略,再验证准确主机范围和浏览器行为。

从资源图开始

如果站点只提供 HTML、本地样式表、一个 favicon、没有任何可执行 JavaScript,那么一条窄策略是可理解的:

Content-Security-Policy: default-src 'self'; base-uri 'self'; form-action 'none'; frame-ancestors 'none'; object-src 'none'; script-src 'none'; style-src 'self'; img-src 'self' data:

script-src 'none' 只有在站点不需要可执行脚本时才是正确的选择。加入搜索、评论或统计标签会改变资源图,并应触发一次有意识的策略复核。

增加传输与嵌套保护

对仅 HTTPS 的站点,下列响应头是常见起点:

Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()

只有当每个子域名都准备好提供 HTTPS 时才启用带 includeSubDomains 的 HSTS。响应头是与未来部署的契约,而不只是扫描器里的一个分数。

检查行为,而不只是存在

请求一个正常页面、一个缺失页面与一个静态资源。错误响应应携带与成功响应同样重要的安全响应头。还要确认压缩与缓存不会改变内容类型,也不会暴露内部路径。

本站的Caddy 示例只是一个起点,不是普适策略。请根据你自己的部署调整主机名、证书处理与应用路由。

通过响应头发送 CSP。meta 策略中的 frame-ancestors 会被忽略,而且它不会继承 default-src;form-action 也需要自己的指令。style-src 'self' 本身不允许内联样式,因此应测试生成的主题,包括深色模式。只有页面确实需要 data 图片时,才在 img-src 中保留 data:。

Content-Security-Policy-Report-Only 可在上线过程中揭示违规,但不会强制执行策略;报告端点还需单独配置。除了查看响应头,也要在真实浏览器中验证执行效果。HSTS 从有效 HTTPS 响应中学习;带有 includeSubDomains 时,它还覆盖设置策略的主机的后代:www.example.test 的策略不覆盖父域 example.test 或同级 api.example.test。确认这个准确范围后,再逐步延长有效期。

来源