# CSP violation (/en/docs/web-security/reporting-api/reports/csp-violation)



A `csp-violation` report tells you that something on the page broke a [Content Security Policy (CSP)](/en/docs/web-security/policies/content-security-policy) 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 [#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 [#payload]

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

<Callout type="info">
  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`.
</Callout>

<CodeBlockTabs defaultValue="application/reports+json (modern)">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="application/reports+json (modern)">
      application/reports+json (modern)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="application/csp-report (legacy)">
      application/csp-report (legacy)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="application/reports+json (modern)">
    ```json
    {
      "type": "csp-violation",
      "age": 53,
      "url": "https://example.com/",
      "user_agent": "Mozilla/5.0 ...",
      "body": {
        "documentURL": "https://example.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://example.com/",
        "sample": "",
        "disposition": "enforce",
        "statusCode": 200,
        "lineNumber": 1441,
        "columnNumber": 59
      }
    }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="application/csp-report (legacy)">
    ```json
    {
      "csp-report": {
        "document-uri": "https://example.com/",
        "violated-directive": "script-src-elem",
        "effective-directive": "script-src-elem",
        "original-policy": "default-src 'self'; report-uri /csp-reports",
        "blocked-uri": "https://apis.google.com/js/platform.js",
        "disposition": "enforce",
        "status-code": 200,
        "script-sample": ""
      }
    }
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## Field reference [#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.                                                                    |
| `referrer`                                   | The 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.                                                                |
| `sourceFile`                                 | Where the violation originated, for inline cases.                                                         |
| `sample` (`script-sample`)                   | First \~40 characters of the offending inline content, only when the directive carries `'report-sample'`. |
| `disposition`                                | `enforce` or `report`.                                                                                    |
| `statusCode` (`status-code`)                 | HTTP status of the document response.                                                                     |
| `lineNumber` / `columnNumber`                | Location 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 [#how-to-receive-it]

Declare an endpoint and point the policy at it with the
[`report-to`](/en/docs/web-security/policies/content-security-policy/directives/report-to)
directive. For the widest browser coverage, send the deprecated
[`report-uri`](/en/docs/web-security/policies/content-security-policy/directives/report-uri)
alongside it; browsers that support `report-to` ignore `report-uri`, so the two
never double-report.

```http
Reporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"
```

```http
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](/en/docs/platform/monitoring/csp).

## What it tells you about security [#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](/tools/csp-evaluator) helps tighten the policy that
produced the reports.

## Gotchas [#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 [#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 [#see-also]

* [Content Security Policy](/en/docs/web-security/policies/content-security-policy)
* [report-uri directive](/en/docs/web-security/policies/content-security-policy/directives/report-uri)
* [CSP violation report fields explained](/en/blog/csp-violation-report-fields)
* [The report delivery format](/en/docs/web-security/reporting-api/concepts/report-delivery-format)
* [Reporting-Endpoints header](/en/docs/web-security/reporting-api/headers/reporting-endpoints)
* [CSP monitoring in CentralCSP](/en/docs/platform/monitoring/csp)

## Sources [#sources]

* [MDN, CSPViolationReportBody](https://developer.mozilla.org/en-US/docs/Web/API/CSPViolationReportBody)
* [W3C, Content Security Policy Level 3 reporting](https://www.w3.org/TR/CSP3/#reporting)
* [MDN, CSP report-uri](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/report-uri)
