What to distinguish before rollout
An enforced Content Security Policy blocks actions that violate its effective rules. These may include required scripts, styles or API calls. A gradual approach helps identify such conflicts before a wider rollout; it does not guarantee an introduction without disruption.
Content-Security-Policy-Report-Only is monitored but not enforced. This means only that this policy does not block anything. A simultaneous Content-Security-Policy remains active. All enforced policies must be satisfied; an additional policy with more sources does not relax an existing restriction. Report-Only cannot be delivered through an HTML meta element. W3C: headers and multiple policies
A simple page visit may look fine while a dialog, password reset or later-loaded script triggers problems. An absence of reports does not prove an absence of errors: the journey may be untested, or the report may not have reached its receiver.
The Wolf-Agents Web Security Check examines CSP headers in the retrieved response. It establishes neither compatibility across every page nor secure nonce generation, actual report delivery or the absence of XSS. A finding may answer a limited header question; the rollout decision needs further evidence.
Interpreting the evidence: CSP can limit script-injection risks. For relevant payment scripts, PCI SSC describes authorisation, integrity, inventory and tampering monitoring, among other matters, in the context of PCI DSS 4.0.1. A nonce, hash or header alone does not establish these processes or confirm complete NIS2 or data protection compliance. PCI SSC: payment page security
Four phases with verifiable transitions
Plan around coverage and resolved findings. A fixed number of days or weeks is not a technical approval criterion.
On narrow screens, scroll the table sideways.
| Phase | Task | Evidence for the next step |
|---|---|---|
| 1. Deliver | Record existing policies and configure the new Report-Only policy and reporting destination. | The actual headers of relevant responses are known; a deliberately triggered report has been traced to the intended receiver. |
| 2. Investigate | Test representative pages, browsers and user journeys; investigate violations. | Documented test scope, reproducible relevant findings and explicitly untested journeys. |
| 3. Adjust | Authorise required resources appropriately or change integrations. | Relevant conflicts explained and affected functions retested with the revised policy. |
| 4. Enforce | Activate the checked version within the intended scope; keep rollback and observation ready. | Functional testing under enforcement, verified delivery and named responsibility for subsequent changes. |
The table describes the evidence needed. It does not report tests carried out here.
Phase 1: configure Report-Only and the reporting destination
First identify every place that sets CSP: application, web server, proxy or CDN, and HTML meta elements where present. Distinguish the already enforced baseline from the new test policy.
The following example shows two HTTP response headers. Each header value occupies one line. The policy is an initial explanatory model, not a tested production template. The HTTPS receiver at example.com is a placeholder that you must set up.
Reporting-Endpoints: csp-endpoint="https://example.com/api/csp-report"
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; report-uri /api/csp-report; report-to csp-endpoint'unsafe-inline' is set only for styles here. In this model, img-src also permits arbitrary HTTPS image sources. Both are deliberately broad permissions that you must assess for your application. The rules are not yet enforced in this mode.
report-to csp-endpoint and the entry of the same name in Reporting-Endpoints belong together. report-uri uses the older reporting path. Supporting browsers prefer report-to and ignore report-uri in the same policy. The older method may still be needed for your browser coverage; it is deprecated. A relative endpoint URL can be resolved against the response URL. Here, the absolute HTTPS address makes the destination explicit. MDN: report-to, W3C: endpoint processing
Phases 2 and 3: investigate reports and correct specific causes
Connect each relevant finding to the page, user action, browser, effective directive and policy version. The browser console, often available through F12, is a starting point. Under Report-Only, a message does not mean the new policy has already blocked the action.
On narrow screens, scroll the table sideways.
| Observation | Question to investigate | Possible correction after investigation |
|---|---|---|
| Report about an inline script | Is this specific script intended, and which script directive applies? | A targeted nonce or hash; alternatively, an appropriate external script. Do not indiscriminately mark every script. |
| Google Analytics or a tag manager affected | Does the issue concern the script, a data connection or an image? Is the integration needed? | Identify the appropriate directive and required source; *.google-analytics.com and *.googletagmanager.com are not a universal fix. |
| Google Fonts affected | Is the stylesheet or font file missing? | Check the roles of fonts.googleapis.com in style-src and fonts.gstatic.com in font-src. This is not a complete provider allowlist. |
| Stripe or PayPal affected | Which specific payment journey, frame, script or network request fails? | Check required sources in script-src, frame-src or connect-src against the actual integration. Do not grant blanket permission for all payment services. |
| WebSocket affected | Which wss:// destination and connection are needed? | Assess the specific destination, for example wss://socket.example.com, for connect-src; do not permit arbitrary WebSocket destinations. |
Browser extensions and interference unrelated to the application can also affect reports. Reports are untrusted input. A reported URL is neither a recommendation to allow it nor reliable proof of an attack. W3C: limits of violation reports
Phase 4: prepare enforcement and rollback
When switching, the checked version is delivered as Content-Security-Policy. The following outline shows only the header-name change; ... is not a usable policy.
Content-Security-Policy-Report-Only: ...
Content-Security-Policy: ...Check the actual responses and retain the configured reporting path where needed for continued analysis. An additional header does not remove an older policy. Retest the intended journeys under enforcement, because only then does the new restriction take effect.
Keep the last known working enforced policy available for rollback. If you temporarily deliver the new version only as Report-Only, it is no longer enforced. An existing working baseline should remain in place. Analyse the specific conflict and check the correction before switching again.
Decide from findings, not elapsed time
The next table is a test template for your application. It assumes a supporting browser, the stated effective directive and no additional blocking policy. Your application's test results remain open. A separate local check of our own below demonstrates selected rule effects; it does not pre-empt testing your user journeys.
On narrow screens, scroll the table sideways.
| Model case | Assumption and expected rule effect | Practical evidence needed | Test status here |
|---|---|---|---|
| Recorded standard journey | An external script served by the application matches script-src 'self'. This rule would permit it under enforcement. | The journey actually executed with the expected functionality, not just a loaded file. | Not executed. |
| Identified need for adjustment | A required inline script does not match script-src 'self'. The Report-Only policy would not block it; the same enforced rule would. | Console finding and traced report, followed by targeted authorisation and another functional test. | Not executed. |
| Infrequent journey not examined | A password-reset dialog has not yet been considered. Its behaviour under the policy is unknown. | Test the dialog and subsequently loaded resources in the relevant states. | Untested; no success can be inferred from absent reports. |
| Message only in the console | A local violation was assumed, but no received report was established. | Demonstrate the same controlled event at the receiver and identify its format and policy. | Report delivery not demonstrated. |
This distinction prevents a green header finding from concealing an unknown user journey. When handing findings to an agency or operator, document the URL, state, browser/version, policy version, expected behaviour, actual result and untested paths. Do not put real personal data into example datasets.
Trace the reporting path
A useful controlled check connects the triggered rule violation to a report actually received. This path consists of several separate steps:
- The document receives the intended CSP and reporting headers.
- A controlled action violates a supported rule.
- The browser generates a report and attempts to send it.
- The intended receiver accepts the appropriate format and identifies the report.
report-uri uses a JSON object containing csp-report, typically with application/csp-report; the Reporting API through report-to uses an array of reports with application/reports+json. The receiver must distinguish the formats actually used. W3C: report formats, MDN: report-uri
The Reporting API provides best-effort delivery. Browsers may delay or discard reports; complete delivery is not guaranteed. Even a working receiver does not turn missing reports into proof of error-free journeys. W3C: reporting guarantees
Limit stored data to what the investigation needs. Reports may contain URLs and other sensitive content; treat them as untrusted input and render them safely in analysis interfaces. Purpose, access and retention must fit your operation. This article does not prescribe a universal retention period.
Schematic explanation · not a measurement
A header does not prove report receipt
- Document and effective policy
The response contains the intended CSP and appropriate reporting headers. Report-Only itself does not block anything; a simultaneous enforced policy may do so.
- Controlled rule violation in the browser
An actually executed action violates a supported rule. The console finding and report generation are local observations.
- Identify the reporting path in use
Older path: report-uri
JSON object containing
csp-report, media typeapplication/csp-report.Newer path: report-to
Named entry in
Reporting-Endpoints. Array of reports, media typeapplication/reports+json.If the browser supports
report-to, it ignoresreport-uriin the same policy. The branches do not promise duplicate delivery. - Delivery attempt
A generated report may arrive late or not at all. The Reporting API guarantees neither complete nor immediate delivery.
- Your configured receiver
Only actual arrival in the appropriate format, linked to the document, rule violation and policy version, establishes receipt.
Process model: each transition needs its own evidence. A received report says nothing about previously untested user journeys. Wolf-Agents does not provide a reporting service here.
Scheduling as an organisational aid
A six-week plan can help organise the work. It is neither a minimum duration nor evidence of successful introduction. Actual evidence matters at each transition.
On narrow screens, scroll the table sideways.
| Example period | Work | What to document |
|---|---|---|
| Week 1 | Connect Report-Only and the receiver | The delivered version and a traced report. |
| Week 2 | Record login, checkout, administration and password-reset journeys where present | Tested states, browsers and journeys still missing. |
| Week 3 | Adjust the policy and integrations | The cause of each relevant conflict and the retest result. |
| Week 4 | Decide on the intended version | Covered functions and explicit remaining limits. |
| Week 5 | Enforce within the approved scope | Functional result under enforcement and available rollback. |
| Week 6 and onwards | Follow changes and analyse findings | Responsibility, triggers and an appropriate frequency for subsequent checks. |
48 hours without a report or seven days without a new violation type do not replace this evidence. Infrequent functions may remain untouched despite a long observation period.
Maintain the policy after introduction
New features, third-party services and library changes may require different resources. Where needed, investigate changed rules in a parallel Report-Only policy while preserving a working enforced baseline. Also check whether existing wildcards or sources are still needed.
You might schedule monthly report reviews and quarterly policy checks if that suits your operation. These are organisational examples, not a general minimum frequency. Critical functional changes need testing when they change, not at the next calendar appointment.
Our functional check and existing reporting evidence
On 29 September 2026, synthetic documents on our own loopback server were tested sequentially with Playwright Chromium 147.0.7727.15, Firefox 148.0.2 and Playwright WebKit 26.4. The functional comparison used the following Report-Only policy and our own receiver at /reports:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'none'; report-uri /reportsThe local document contained an external script served by the application and a direct inline script without authorisation. For enforcement, the same policy value was delivered in the Content-Security-Policy header; a third case delivered both headers simultaneously. The snippet does not set up a receiver and is not a universal policy for your website.
On narrow screens, scroll the table sideways.
| Delivered policy | External script served by the application | Inline script without authorisation | Separate reporting evidence |
|---|---|---|---|
| Report-Only alone | Executed. | Executed; violation with disposition report. | Browser event and actual POST to our collector. |
| Enforced | Executed. | Blocked; violation with disposition enforce. | Browser event and actual POST to our collector. |
| Report-Only and enforced in parallel | Executed. | Blocked by the effective enforced policy. | Report receipt checked separately from functional observation. |
This check used only report-uri: each received payload was a JSON object containing csp-report with application/csp-report. This is not a modern Reporting API report or a promise of delivery timing. The nonce check adds the subsequent positive case of targeted script authorisation.
Modern reporting: use the existing evidence within its narrow limits
For report-to and Reporting-Endpoints, a separate check of our own from 28 September 2026 is available: Chrome 153.0.8010.54, headless, using a fresh normal disposable profile and a private context respectively. Our HTTPS collector actually received application/reports+json containing an array and the report type csp-violation. The Reporting API chapter explains the details.
Both runs used --short-reporting-delay and observed each case for 35 seconds; --disable-background-networking was excluded from Playwright's launch defaults. TLS used only an SPKI exception for our disposable certificate. There was no global certificate exception or change to the system trust store. This accelerated diagnostic demonstrates neither normal delivery latency nor equivalent Firefox/WebKit behaviour nor support for an arbitrary third-party collector. With a deliberately mismatched endpoint name, neither a modern report nor a legacy fallback arrived within the observation window.
Test limit: These are isolated functional and transport checks with synthetic content. They did not test real login, checkout, password reset, extensions, gateways or your entire browser population. Follow the approach of inventory, controlled receipt check, functional testing and deliberate rollback.
Relevant further reading
For an initial finding about the publicly accessible configuration, you can open the Web Security Check. Its stated measurement scope still applies when you have already prepared a rollout checklist.
Frequently asked questions
How long should the Report-Only phase last?
A fixed minimum duration does not establish readiness for rollout. Test representative browsers, pages and journeys, including infrequent functions, and check report receipt. Resolved relevant violations and successful functional tests support a conclusion about the scope actually examined.
What should I do if the site does not work under enforcement?
Where possible, restore the last known working enforced policy. If you temporarily investigate the new version using only Report-Only, that version is no longer enforced. Preserve an existing working baseline, investigate the violation and check the correction before switching again.
Can I use different policies for different pages?
Yes, if your delivery system can set the appropriate headers for each response. Match the policy to the functionality needed. An administration area does not automatically need a looser policy; inline scripts can be authorised specifically. Check paths, response states and interactions with additional headers.
Should I disable reporting after the switch?
Continued analysis can reveal changes and new conflicts. Keep it where it serves a clear operational purpose, and define responsibility and frequency. Reporting is neither complete evidence of an attack nor a replacement for functional tests; data scope and retention remain separate decisions.
Primary sources were checked on 29 September 2026, including the CSP3 Working Draft of 16 September 2026 and the reporting specification. Our local check and reused Chrome reporting evidence are described separately above. Wolf-Agents does not offer a reporting or monitoring service through this guide.