Safeguard
Security Guides•

report-to or report-uri: how do you collect CSP violation reports?

Use report-to with a Reporting-Endpoints header to collect CSP violations, and keep report-uri as a fallback. See the setup, report format and rollout.

Safeguard Security Team
4 min read

Collect CSP violations with the report-to directive, which names an endpoint declared in a Reporting-Endpoints header. The older report-uri directive is deprecated, but MDN says you can send both until report-to is widely supported. Browsers that understand report-to ignore report-uri.

The two mechanisms

report-urireport-to
StatusDeprecatedCurrent
ValueA URLAn endpoint name
Where the URL livesIn the policyIn the Reporting-Endpoints header

MDN states that report-to is intended to replace report-uri, and that in browsers supporting report-to, the report-uri directive is ignored.

Setting it up

The mapping between an endpoint name and its URL is defined in a separate header. MDN notes that non-secure endpoints are ignored, so the URL must be HTTPS.

Reporting-Endpoints: csp-endpoint="https://reports.example.com/csp"
Content-Security-Policy: default-src 'self'; report-to csp-endpoint

For wider support during the transition, MDN shows both directives together:

Content-Security-Policy: default-src 'self'; report-uri https://reports.example.com/csp; report-to csp-endpoint

What a report looks like

With report-to, reports are JSON sent by POST with a Content-Type of application/reports+json. Each carries a type of csp-violation and a body with fields including the blocked URL, the effective directive, the document URL, the source file, line and column, the disposition (enforce or report) and the original policy. The sample field holds a short excerpt of the offending code when available.

Treat these as untrusted input. They arrive from browsers anyone can drive, so a public endpoint can receive junk. Validate size and shape, rate limit, and never render the fields as HTML in a dashboard.

Handling the volume

Reports can arrive in large numbers on a busy site. Decide up front what you will keep. A simple approach is to store only the effective directive, the blocked URL host, the document path and a count per day, and to sample the rest. Group by blocked host first: a new host that appears suddenly is more interesting than a million repeats of an old one.

Browser extensions are the usual noise. Reports whose source file is not on your domain and whose blocked URL is a scheme such as an extension URL can be filtered out of alerts, though it is worth keeping a count in case the pattern changes.

A rollout that avoids noise

  1. Start with Content-Security-Policy-Report-Only. MDN says both a report-only and an enforcing policy can be present, and each is honoured. Violations from the report-only one are sent but not blocked.
  2. Group reports by effective directive and blocked URL. Expect a long tail from browser extensions, which is normal.
  3. Fix real first-party issues first: inline handlers, forgotten third-party tags.
  4. Promote the policy to enforcing. Keep a report-only copy of the next, tighter version running beside it.
  5. Alert on new blocked hosts, not on raw volume.

Report-only policies cannot be delivered in a meta element, and the report-to directive is not supported there either, so reporting needs real response headers. Static sites on hosts that do not allow custom headers lose this option.

For a longer walk through enforcement, see CSP report-only rollout steps.

Quick check

Can I use only report-uri today?

It is deprecated, so plan to move. Sending both is the transition path MDN describes.

Why do I get reports for scripts I never added?

Often browser extensions or injected ads. Filter by source file and blocked URL before assuming a compromise.

Safeguard's policies and gates can block risky dependencies at pull request time, which reduces how many unexpected scripts reach the browser in the first place. Try a free scan at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.