必须启用mod_headers模块且使用header always set才能使csp在所有响应(含404/500)中生效,子路径需显式配置,后定义的同名header会覆盖前序设置。

直接加 Header 指令就能生效,但必须确认 mod_headers 已启用
Apache 默认不启用 mod_headers,即使配置了 Header set 也不会生效,且不会报错——这是最常被忽略的前提。用 apachectl -M | grep headers 查看是否已加载;若无输出,需先执行 a2enmod headers(Debian/Ubuntu)或在 httpd.conf 中取消 #LoadModule headers_module modules/mod_headers.so 的注释。
Header set 和 Header always set 的区别决定 CSP 是否对错误响应生效
典型 XSS 防御场景中,你希望即使返回 404 或 500 也带上 CSP,防止攻击者利用错误页面注入脚本。这时必须用 Header always set Content-Security-Policy,而不是 Header set。后者只作用于成功响应(2xx),而前者覆盖所有状态码。
常见写法示例:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https:; object-src 'none'; base-uri 'self';"
-
'unsafe-inline'要谨慎:除非你有内联<script></script>或onclick=,否则应移除 -
https:允许任意 HTTPS 外部脚本,比*:安全,但仍扩大了攻击面 -
base-uri 'self'防止攻击者通过<base href="...">劫持后续相对 URL
Location /admin 下的 CSP 需单独配置,继承规则不自动向下传递
Apache 的 Header 指令不支持“子路径自动继承”,比如你在 <virtualhost></virtualhost> 里设了全局 CSP,/admin 路径下仍可能需要更严格的策略(如禁用 unsafe-inline)。必须显式用 <location></location> 或 <directory></directory> 包裹新规则。
PHP中文网提供Apache 2.4.62 官方 tar.gz 源码包下载,通过源码编译安装,开发者能够灵活定制模块、优化性能并精准控制安装路径,满足多样化的业务需求。
注意顺序:后出现的 Header always set 会覆盖前面同名 Header,所以位置靠后的配置优先级更高。
开发环境用 report-uri 或 report-to 时,务必检查 Apache 是否允许 POST 到该路径
启用违规上报(如 report-uri /csp-report)后,浏览器会向该路径发 POST 请求,但默认 Apache 可能拒绝非 GET/HEAD 的静态路径请求。如果看到 405 Method Not Allowed 错误,说明后端没处理该 endpoint——要么配一个真实接收上报的脚本(如 PHP/Python),要么在对应 <location></location> 中显式允许:Require all granted 并确保没有 LimitExcept 拦截 POST。
另外,report-to 是较新语法,老版本 Chrome(report-uri 兼容。










