Chapter 2 · Practice 3 of 3
Roll out CSP in report-only mode and watch the reports
Why it matters
Switching on a strict CSP in one go usually breaks something: an inline event handler, an analytics snippet, a browser extension's injected script showing up in reports. OWASP's rollout approach:
- Send the strict policy as
Content-Security-Policy-Report-Only. It blocks nothing and reports every violation. - Optionally keep a looser policy enforced at the same time.
- Fix your code: move inline handlers (
onclick=) toaddEventListener, add nonces, removeeval. - When reports are only noise (extensions, old browsers), switch the header to enforcing.
- Keep reporting on, so regressions show up.
Reporting directives. report-to is current: it names an endpoint defined in the Reporting-Endpoints header. report-uri is deprecated but still used by older browsers, so OWASP recommends sending both.
Expect some noise. Group reports by blocked-uri and violated-directive, ignore known extension schemes, and alert on new patterns rather than volume.
Avoid
- Adding 'unsafe-inline' or 'unsafe-eval' to silence reports
- Enforcing a new policy without a report-only period
Example
Reporting-Endpoints: csp="https://example.com/csp-reports"
Content-Security-Policy-Report-Only: script-src 'nonce-r4nd0m' 'strict-dynamic';
object-src 'none'; base-uri 'none'; require-trusted-types-for 'script';
report-to csp; report-uri https://example.com/csp-reports