Introduce CSP with Report-Only: a practical rollout
Observe violations, test essential journeys and enforce only the policy you have verified.
check.uk.app technical team · Reviewed 26 September 2026
Start with a test environment
Save current response headers and proxy configuration. List the origins needed by sign-in, payments, CAPTCHA, fonts and analytics. Keep the existing enforced CSP: an observation policy does not replace or relax it. Plan a rollback before changing the header.
Add a candidate policy in Nginx
Place this directive in the appropriate server or location block on your test site. It is a restrictive observation example, not a ready-made production policy. It allows same-origin sources, flags inline scripts and external sources, and does not block them by itself.
The always parameter includes error responses. In Nginx 1.26.3, defining add_header in a nested location prevents inheritance of parent add_header directives. Preserve existing security headers and inspect each affected route. Do not blindly append a second copy of a header already supplied by your application.
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'" always;Inspect a real response and browser behaviour
Run nginx -t for your installation before reloading its service. Open the test page in browser developer tools: confirm the response contains Content-Security-Policy-Report-Only, then inspect Console while exercising the page. This sample is for local browser observation; it does not configure a server-side report collector.
For collection, configure a working HTTPS endpoint and Reporting-Endpoints together with report-to. The older report-uri has different payload semantics and compatibility. Apply payload limits and retention rules; report URLs can contain user data. Do not send reports to an example address.
Use a controlled before-and-after test
Our isolated test uses an external same-origin script and an inline script. With this Report-Only header both run, while the inline violation is reported. With the same policy enforced through Content-Security-Policy, the external script runs and the inline script is blocked. Test your own pages: this fixture does not certify third-party integrations.
Resolve each required source deliberately. For necessary inline code, use application-generated nonces or verified hashes rather than broad unsafe-inline permissions. A nonce must be unpredictable and freshly generated for each response; a fixed copied value is not a solution.
Enforce gradually and verify rollback
After representative user journeys pass, move the tested policy to the enforced header in staging first. Check login, recovery, checkout, embeds and error pages again. Multiple enforced policies combine restrictions; a new header cannot loosen an existing one. Restore the saved configuration if legitimate flows fail.
check.uk.app observes returned headers; it does not execute the application to validate CSP coverage. Test environment: Nginx 1.26.3 plus Chromium-based Microsoft Edge, 26 September 2026. No production CSP was changed for this example.