A Content Security Policy (CSP) restricts which resources browsers can load for your site, cutting the damage from cross-site scripting attacks. The safest way to deploy one is to start in Report-Only mode — which logs violations without blocking anything — and switch to enforcement only after you have a working allowlist.
Set this header instead of Content-Security-Policy. The two headers use identical syntax, but Report-Only never blocks anything — it only logs violations to the browser console.
Content-Security-Policy-Report-Only: default-src 'self'
Why Report-Only first? Deploying an enforcing CSP on a live site without testing it first is one of the most common ways teams accidentally break their own site. Inline scripts, analytics tags, fonts from CDNs, and dynamically injected content will all violate a strict default-src 'self' policy. Report-Only lets you discover every violation before a single user is affected.
Add this header using the same mechanism you use for other security headers — your web server config, CDN headers file, or application middleware. See the Security Headers guide for how to set headers across different platforms.
Open your browser's developer tools (Console tab), visit your site, and use every feature — load all pages, trigger all interactions, and exercise authenticated flows if your site has them.
Each CSP violation appears as a console error. The message identifies:
script-src, style-src)Collect violations until you have exercised the full site. Violations that only appear on specific pages or for authenticated users are easy to miss.
Add each legitimate source origin to the appropriate directive. Start from your Report-Only header and add sources one by one:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:
Two common patterns to handle carefully:
'unsafe-inline' (which undermines most of CSP's XSS protection), use a nonce. Each response includes a unique random value in the header (script-src 'nonce-abc123') and the same value as an attribute on each inline script tag (<script nonce="abc123">). Browsers allow scripts with a matching nonce and block everything else.* as a source. A wildcard in script-src allows scripts from any origin, removing most protection. Prefer explicit origins.After each update to your Report-Only policy, revisit your site and check for new violations. Repeat until the console shows zero violations across all pages and features.
Common sources of violations that appear late in testing:
Do not switch to enforcement until you are confident the policy is complete.
Rename the header from Content-Security-Policy-Report-Only to Content-Security-Policy. The policy syntax is identical — only the header name changes.
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:
From this point on, browsers will block any resource that violates the policy. If a new third-party resource is added to your site in future without updating the CSP, it will be silently blocked for users.
Run the Headers tool on your domain. It confirms the enforcing Content-Security-Policy header is present and flags common weaknesses such as 'unsafe-inline' in script-src or overly broad wildcard sources.
Continue to monitor browser consoles after deployment. New site features, A/B tests, or third-party script updates can introduce violations that you will need to add to your policy.