CSP report-uri vs report-to migration guide

Direct Answer: Core Differences & Migration Trigger

The report-uri directive is the legacy CSP reporting mechanism that fires individual JSON POST requests per violation. The report-to directive leverages the modern Reporting API to batch, queue, and route violations to grouped endpoints with configurable retention and retry logic. Migration is mandatory for CSP Level 3 compliance and eliminates header parsing overhead. Deploy both directives simultaneously during transition, then decommission report-uri once telemetry confirms stable report-to delivery. For foundational header architecture and policy scoping, reference Web Security Headers Fundamentals before modifying production response chains.

Security Implications: Dual-header deployment prevents reporting gaps during browser compatibility transitions. Removing report-uri prematurely causes silent failures in Safari <15 and Firefox <70.

Exact Configuration & Diagnostic Commands

Deploy the Report-To header first to register the endpoint group, then attach it via report-to in the CSP header. Maintain report-uri as a fallback during the transition window.

Nginx

add_header Report-To '{"group":"csp-collector","max_age":86400,"endpoints":[{"url":"https://report-collector.yourdomain.com/api/violations"}]}' always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.yourdomain.com; report-uri https://legacy-collector.yourdomain.com/legacy; report-to csp-collector" always;

Apache

Header always set Report-To '{"group":"csp-collector","max_age":86400,"endpoints":[{"url":"https://report-collector.yourdomain.com/api/violations"}]}'
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.yourdomain.com; report-uri https://legacy-collector.yourdomain.com/legacy; report-to csp-collector"

Diagnostic Commands

# Verify header injection
curl -sI https://yourdomain.com | grep -iE 'report-to|content-security-policy'

# Test endpoint payload acceptance
curl -X POST -H 'Content-Type: application/reports+json' -d '{"type":"csp-violation","age":0,"url":"https://yourdomain.com","body":{"document-uri":"https://yourdomain.com","violated-directive":"script-src","original-policy":"default-src self;"}}' https://report-collector.yourdomain.com/api/violations

When structuring complex directive chains, align parsing order with Content Security Policy (CSP) Essentials to prevent browser-level truncation.

Verification & Endpoint Validation

Trigger a controlled violation to validate payload routing and HTTP response codes.

  1. Inject test payload: <script src="https://unauthorized-domain.com/test.js"></script>
  2. Open browser DevTools > Network tab. Filter by report-to or violations.
  3. Confirm POST request contains Content-Type: application/reports+json.
  4. Validate JSON body includes type: "csp-violation", body.document-uri, body.violated-directive, and body.original-policy.
  5. Check collector logs for HTTP 200/204. HTTP 400/404 indicates malformed endpoint or missing CORS preflight.
  6. Run curl -v -X POST -H 'Content-Type: application/reports+json' -d '{}' https://report-collector.yourdomain.com/api/violations to verify endpoint accepts Reporting API payloads without CSP context.

Security Implications: Unvalidated endpoints expose violation data to interception. Enforce TLS 1.2+ on the collector and restrict origin via Access-Control-Allow-Origin.

Edge Cases & Rollback Procedures

Handle legacy browser gaps, header size limits, and collector failures with deterministic fallbacks.

Edge Case Handling

Rollback Procedure

  1. Immediate revert: Remove Report-To header and report-to directive from CSP.
  2. Apache: Header unset Report-To + Header set Content-Security-Policy "default-src 'self'; report-uri https://legacy-collector.yourdomain.com/legacy"
  3. Nginx: Remove add_header Report-To line + strip report-to from add_header Content-Security-Policy.
  4. Restart web service: systemctl reload nginx or systemctl reload apache2.
  5. Verify fallback: Re-run curl -sI and confirm only report-uri persists in response headers.

Security Implications: Rollback restores legacy reporting but sacrifices batch efficiency and retry resilience. Document the 48-hour monitoring window before permanent report-uri decommission.