CSP Violation Reports

Browsers report policy violations to /api/csp-report when CSP is set with report-uri. Per-report details (blocked URL, source file, line number) stream to Cloudflare Workers Logs. Counters below are aggregated per UTC day.

← Back to admin dashboard

Last 7 days

Date (UTC)Total violationsBy hostname
2026-10-070
    2026-10-080
      2026-10-090
        2026-10-100
          2026-10-110
            2026-10-120
              2026-10-130

                How to read this

                CSP reports only flow when you add report-uri /api/csp-reportto the CSP header (set in Cloudflare Dashboard → Transform Rule → Modify Response Header). Recommended setup:

                1. Phase 1 — Deploy report-only CSP: send Content-Security-Policy-Report-Only with current policy + report-uri. Don't change enforcement yet — just collect.
                2. Phase 2 — Monitor for 30 days: review /admin/csp-reports + Workers Logs for violations. Identify scripts/dirs to whitelist.
                3. Phase 3 — Tighten policy: remove 'unsafe-inline' / 'unsafe-eval' where possible, switch to nonces (Phase 7.2).
                4. Phase 4 — Switch to enforcing: replace Report-Only with real Content-Security-Policy header.

                Why this matters: Current CSP uses 'unsafe-inline' because of legacy monetization scripts (Propush, Monetag, Mediavine). Report-only mode lets us measure the actual cost of tightening before enforcing. Most CSP migration failures happen because teams don't see what they break first.

                Cloudflare Logs query examples

                # Tail logs and grep for CSP violations
                wrangler pages deployment tail --project-name=salarylab \
                  | grep "event_type":"csp_violation"
                
                # Count by violated directive
                wrangler pages deployment tail --project-name=salarylab \
                  | grep -oE "violated_directive":"[^"]+" \
                  | sort | uniq -c | sort -rn | head -10
                
                # Per-host breakdown
                wrangler pages deployment tail --project-name=salarylab \
                  | grep -oE "document_uri":"https?://[^/]+" \
                  | sort | uniq -c | sort -rn | head -10