CentralCSP
Reporting APIReport types

CSP violation

The csp-violation report, what the browser sends when a Content Security Policy is violated, in both the modern and legacy formats.

Last update:

A csp-violation report tells you that something on the page broke a Content Security Policy (CSP) rule: a blocked script, style, image, frame, or connection. It is the most useful report type for tightening a policy, because each one names the directive that fired and the resource that was blocked. There are two payload formats for the same event, the modern Reporting API form and the legacy report-uri form.

When the browser sends it

The browser sends one report each time the policy blocks (or, in Report-Only mode, would block) a resource or an inline violation. It fires in both modes; the disposition field tells them apart (enforce for a blocking policy, report for Report-Only). Reports are de-duplicated, so a resource blocked many times does not produce one report per attempt.

Payload

The same violation is delivered in two shapes depending on which directive routed it. Switch between them here:

The report-uri directive posts a single object wrapped in csp-report with kebab-case fields and Content-Type: application/csp-report, not the application/reports+json array. The two are not interchangeable; an endpoint that accepts both must branch on the Content-Type.

{
  "type": "csp-violation",
  "age": 53,
  "url": "https://api-next.centralcsp.com/",
  "user_agent": "Mozilla/5.0 ...",
  "body": {
    "documentURL": "https://api-next.centralcsp.com/",
    "referrer": "https://www.google.com/",
    "blockedURL": "https://apis.google.com/js/platform.js",
    "effectiveDirective": "script-src-elem",
    "originalPolicy": "default-src 'self'; report-to csp-endpoint",
    "sourceFile": "https://api-next.centralcsp.com/",
    "sample": "",
    "disposition": "enforce",
    "statusCode": 200,
    "lineNumber": 1441,
    "columnNumber": 59
  }
}

Field reference

The modern body uses camelCase; the legacy form uses the kebab-case name in parentheses.

Field (legacy name)Meaning
documentURL (document-uri)The page where the violation happened.
referrerThe document referrer, if any.
blockedURL (blocked-uri)The resource that was blocked. Truncated to scheme, host, and port when cross-origin.
effectiveDirective (effective-directive)The directive that actually fired (for example script-src-elem).
originalPolicy (original-policy)The full policy text the browser enforced.
sourceFileWhere the violation originated, for inline cases.
sample (script-sample)First ~40 characters of the offending inline content, only when the directive carries 'report-sample'.
dispositionenforce or report.
statusCode (status-code)HTTP status of the document response.
lineNumber / columnNumberLocation for inline violations.

The legacy violated-directive is a historic alias for effective-directive. Treat every field as attacker-influenced input, and never render one into a page unescaped.

How to receive it

Declare an endpoint and point the policy at it with the report-to directive. For the widest browser coverage, send the deprecated report-uri alongside it; browsers that support report-to ignore report-uri, so the two never double-report.

Reporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"
Content-Security-Policy:
    default-src 'self';
    report-uri https://<Endpoint-ID>.report.centralcsp.com;
    report-to csp-endpoint

CentralCSP ingests both formats and normalizes them, which is the basis of the CSP violation dashboard.

What it tells you about security

Read effectiveDirective and blockedURL together. A script-src violation pointing at a host you recognize usually means the policy is too strict. One pointing at a host you do not recognize, or an inline sample you did not write, is worth investigating as a possible injection. A sudden spike in a directive is the signal to look. The CSP evaluator helps tighten the policy that produced the reports.

Gotchas

The body field names are camelCase in the modern form and kebab-case in the legacy form. The disposition value per the spec WebIDL is enforce or report, though some MDN prose writes reporting; expect report. And blockedURL is deliberately redacted to scheme, host, and port for cross-origin resources, so you see the origin rather than the exact path.

Browser support

The legacy report-uri delivery has the broadest support, including Firefox and Safari. The modern report-to delivery is Chromium-led, which is why sending both is the widest-coverage setup today.

See also

Sources

On this page