启用CSP Report-Only本意是先观察违规,不影响客户访问。上线后页面确实没被拦,但var/log和接收CSP report的访问日志每小时增长几个GB,最后MySQL也因为磁盘不足异常。Report-Only“不拦截”不代表没有运行成本:一个页面上的第三方脚本可能触发几十条报告,每个访客都会重复提交。

先分清是哪一种日志在涨

du -h --max-depth=2 var/log /var/log/nginx | sort -h | tail -30
find var/log /var/log/nginx -type f -size +500M -printf "%s %p\n" | sort -n

可能是Magento csp.log、system.log,也可能是Nginx记录POST /csp/report的access log,或者日志代理把每条报告复制到远端又本地缓存。先找到文件和写入进程,别直接全局关闭日志。

对报告做去重和采样

CSP报告通常包含document-uri、blocked-uri、effective-directive和source-file。把这些字段规范化后计算fingerprint,同一fingerprint在时间窗口内只记录一次并累加计数。query string、行号等高基数字段可按需要移除。

fingerprint = sha256(
  effective_directive + "|" + normalized_blocked_uri + "|" + source_file
)
rate limit by site + fingerprint + minute

接收端要限制Body大小、Content-Type和请求速率。不要把完整Cookie、Authorization或包含个人参数的document-uri写入日志。

修策略,而不是永远吞报告

  • 自有静态域名加入精确的script-src/style-src/img-src白名单
  • 第三方域名只放开实际需要的指令,不用*
  • nonce或hash配置与模板输出保持一致
  • 浏览器扩展产生的噪声单独识别,不加入网站白名单
  • 重复的内联脚本逐步迁移或使用安全nonce

Magento模块可以在csp_whitelist.xml中声明资源。每次放行前确认域名所有权和资源类型,不要因为一条错误就把整个https:加入script-src。

日志轮转与磁盘保护

/var/log/nginx/csp-report.log {
  daily
  rotate 7
  compress
  missingok
  notifempty
  postrotate
    systemctl reload nginx >/dev/null 2>&1 || true
  endscript
}

logrotate是最后防线,不是根因修复。还应设置磁盘告警、日志配额以及采集端背压,避免远端不可用时无限堆本地spool。

从Report-Only切到Enforce前

  • 覆盖首页、分类、商品、购物车、结账、后台支付回跳等关键页
  • 至少观察一个完整业务周期和主要浏览器
  • 关键违规归零或有明确例外
  • Enforce先按小流量或单Store灰度
  • 准备快速回退,但不回退到无限白名单
CSP报告本身也是外部输入。要像处理Webhook一样做大小限制、速率限制、脱敏和聚合。