CentralCSP
Reporting APIReport types

Script hash

The csp-hash report sends a hash of every script the page loads, the basis for a browser-side script inventory.

Last update:

A csp-hash report carries the hash of a script (or other subresource) the page loaded. Unlike a violation report, it is not about something being blocked: you opt in with a 'report-sha256' source expression and the browser reports a hash for every matching resource. That stream is how you build an inventory of the scripts actually running in the browser, mapped to library, version, and known CVEs.

Chromium-only

Script hash reporting ships enabled by default in Chromium, so it is on without an origin trial, but it is Chromium-only: Firefox and Safari do not send it. The field casing also differs from the CSP draft (see Gotchas), so treat the payload as Chromium-specific. See Browser support below.

When the browser sends it

When a script-like directive carries 'report-sha256' (or 'report-sha384' / 'report-sha512'), the browser emits one csp-hash report for each matching resource it loads, and also prints the hash to the DevTools console. It reports rather than blocks, so it does not affect what runs. Hash reports are not exposed to ReportingObserver; they only go to the endpoint.

Setup

Reporting-Endpoints: hashes-endpoint="https://<Endpoint-ID>.report.centralcsp.com"
Content-Security-Policy-Report-Only: script-src 'self' 'report-sha256'; report-to hashes-endpoint

Payload example

{
  "type": "csp-hash",
  "age": 12,
  "url": "https://api-next.centralcsp.com/",
  "user_agent": "Mozilla/5.0 ...",
  "body": {
    "documentURL": "https://api-next.centralcsp.com/",
    "subresourceURL": "https://api-next.centralcsp.com/main.js",
    "hash": "sha256-85738f8f9a7f1b04b5329c590ebcb9e425925b6c0d...",
    "type": "subresource",
    "destination": "script"
  }
}

Every csp-hash report body carries these fields inside the shared report envelope.

Field reference

FieldMeaning
documentURLThe page the script loaded on.
subresourceURLThe URL of the loaded script or resource.
hashThe hash as <alg>-<base64>, for example sha256-....
typeThe hash category (for example subresource).
destinationThe request destination, for example script.

How to receive it

Declare an endpoint and add 'report-sha256' to script-src; keep the policy in Report-Only so it never blocks. This is the exact mechanism behind the CentralCSP script inventory and SBOM, which maps each reported hash to a technology, version, and known CVEs, with no snippet or browser extension required.

What it tells you about security

A script hash you did not deploy is a supply-chain signal: a tampered CDN asset, an injected formjacking or Magecart script, or an unexpected third party. Continuous hash reporting plus alerting on new or changed hashes is how you catch that change the moment it reaches a real browser, rather than in a post-incident review.

Gotchas

Field casing is unsettled: Chromium emits camelCase (documentURL, subresourceURL) while the CSP editor draft example uses snake_case (document_url, subresource_url). Confirm against a live capture.

An earlier design used a 'report-hashes' keyword; the shipped keyword is 'report-sha256' (and the sha384/sha512 variants). The keyword and report shape are still evolving in the CSP draft, so expect them to change.

Browser support

Chromium-based browsers only, where it ships enabled by default. Firefox and Safari do not support it. The field shape follows Chromium rather than the CSP draft, so treat any captured payload as Chromium-specific.

See also

Sources

On this page