In one paragraph
Content-Security-Policy-Report-Only without an enforced policy means the browser evaluates proposed restrictions without blocking violations under that policy. This is useful during deployment but is not equivalent to active protection. Validate reports and important user journeys, then publish the tested restrictions in Content-Security-Policy. Keep a separate report-only candidate if you want to test the next improvement.
Why it matters
Report-only mode separates observation from enforcement. A violation report can reveal a legitimate dependency you forgot or an unexpected execution path, but the report-only rule itself does not stop that action. Existing independent controls may still apply, so assess the complete response rather than declaring the whole application unprotected.
The operational failure is often an unfinished rollout: a header was added, but no team owns report review or promotion. A quiet reporting endpoint can also indicate broken reporting instead of a clean policy. Confirm that reports are received before relying on their absence.
How WebAuditOS evaluates this finding
The supplied rule grades HTML responses containing a Report-Only header. An additional enforcing CSP satisfies this presence check; without an enforcing header it warns at low severity. No Report-Only header or a non-HTML response is not graded.
This does not assess the enforcing policy's strength. A minimal or permissive policy can clear this finding without providing the intended script restrictions. A policy enforced through an HTML meta element is outside the response-header check, although browsers support a subset of CSP that way. Verify the effective policy rather than treating any passing header as sufficient.
How to fix it
- Inventory all policies on the final document response. Distinguish Content-Security-Policy from Content-Security-Policy-Report-Only and check whether the application, CDN, or proxy adds another policy.
- Establish a working reporting path. A Reporting API setup can use:
Reporting-Endpoints: csp="https://example.com/csp-reports"
Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; base-uri 'self'; report-to csp
This is an illustrative candidate, not a policy ready for every application. Implement the endpoint before relying on it. report-uri is deprecated but may still be supplied for compatibility while report-to support varies.
- Trigger a controlled violation in a safe environment and confirm reporting. Review format, retention, access, and rate handling; reports are untrusted input and may contain sensitive URL information. Do not automatically turn their contents into allowlist entries.
- Cover real page types and interactions. Test sign-in, checkout, account screens, embeds, and rarely used tools. Classify violations into required dependencies, application changes, suspicious activity, and extension-related noise. Investigate rather than blindly discarding unfamiliar sources.
- Correct the complete candidate. Preserve nonce or hash handling where used, remove unnecessary dynamic evaluation, and allow only required sources. An overly broad wildcard can make reports disappear by discarding meaningful restrictions.
- Publish the tested candidate under Content-Security-Policy. Keep a report-only header for a distinct future revision if useful; the browser enforces one and evaluates the other independently. Do not assume that an additional permissive policy overrides a restrictive enforced policy.
- Verify final response headers, Console messages, reports, and complete browser journeys after deployment. Rescan in WebAuditOS and continue monitoring. A screenshot of the homepage cannot validate a checkout policy.
What the fix can break
Enforcement blocks violations that were previously only reported. Missing scripts, API calls, fonts, or frames can leave parts of a page broken while the server returns 200. A report-only success therefore needs representative traffic and intentional tests.
Inline handlers and third-party loaders often require actual code changes rather than another allowed hostname. Dynamic nonces must remain aligned with your caching design.
Prepare a controlled rollback of the enforced policy and retain evidence of which restriction caused the problem. Returning temporarily to observation may restore functionality, but it also removes that enforcement and should not become the unnoticed final state.
Questions
Can both CSP headers be present?
Yes. Their roles differ: one enforces its restrictions and the other evaluates a candidate without enforcing it. Keep both configurations understandable to maintainers.
How long should report-only testing last?
Long enough to cover relevant traffic patterns and critical journeys with verified reporting. No fixed number of days proves completeness.
Does an enforcing header automatically mean strong CSP?
No. This rule checks its presence, not whether it effectively restricts scripts or other resources. Review the policy itself.
What should I read next?
Review missing CSP and default-src fallbacks before declaring the rollout complete.