必须启用mod_headers模块并使用header always set,否则csp无法在404/500等错误响应中生效;需全局配置、避免被后端或cdn覆盖,且策略须适配实际资源来源以防白屏。

在 Apache 中用 mod_headers 配置 Content-Security-Policy(CSP)是防御 XSS、数据注入和非法资源加载的关键手段。它不依赖前端代码,直接由服务器注入响应头,对所有请求路径生效,但必须精准适配站点实际资源来源,否则容易导致页面白屏或功能异常。
确保 mod_headers 已启用并使用正确语法
Apache 2.4+ 推荐用 Header always set 而非 Header set,避免被后端应用或代理覆盖。先确认模块已加载:
- Debian/Ubuntu 系统执行:
a2enmod headers && systemctl restart apache2 - CentOS/RHEL 检查
httpd.conf中是否取消注释:LoadModule headers_module modules/mod_headers.so - 配置位置建议放在虚拟主机块内(
<virtualhost></virtualhost>),或全局安全配置文件(如/etc/apache2/conf-enabled/security.conf)中
写一个基础但可用的 CSP 策略
不要直接套用“全站 default-src 'self'”,WordPress、CDN、统计脚本、字体库等都会因此报错。从最小可行策略起步,逐步收紧:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 允许同源脚本和样式:
script-src 'self'; style-src 'self' - 若使用 Google Fonts:
style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com - 若含内联脚本(如 WordPress 主题常用):
script-src 'self' 'unsafe-inline'(临时方案,后续应迁移到 nonce 或 hash) - 禁止插件类资源:
object-src 'none'; base-uri 'self' - 完整示例:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data:; font-src 'self' https://fonts.gstatic.com; object-src 'none'; base-uri 'self'; form-action 'self';"
避开常见陷阱
CSP 配置失败往往不是语法错误,而是作用域或覆盖逻辑出问题:
- 多个
Header always set Content-Security-Policy指令共存时,后定义的会覆盖前一个;若需合并策略,必须手动拼接成一条完整指令 - PHP 或反向代理(如 Node.js)可能自行输出 CSP 头,导致重复或冲突;可在代理配置中加
Header unset Content-Security-Policy清除上游头再重设 - WordPress 子目录(如
/wp-admin/)若继承了过于严格的根目录 CSP,会导致后台空白;可在该子目录的.htaccess中添加Header unset Content-Security-Policy单独解除 - 首次部署建议先用
Content-Security-Policy-Report-Only头收集违规日志,确认无误后再切换为正式策略
验证是否真正生效
打开浏览器开发者工具 → Network → 刷新任意页面 → 查看响应头中是否存在 Content-Security-Policy,且值与配置完全一致。重点检查:
- 是否在 404、500 等错误响应中也存在(靠
always保证) - 是否被 CDN(如 Cloudflare)或 WAF(如 ModSecurity)覆盖或改写
- 浏览器控制台是否有
Refused to load...类报错,说明策略过严,需回溯调整










