Report Content Security Policy violations
Two response headers make the browser report every violation of your Content Security Policy to fastmon.
Naming fastmon as your policy's report endpoint makes the browser send every violation to fastmon. A new or tightened policy can run as Content-Security-Policy-Report-Only first, so you see what it would break before it blocks anything. What the reports show is on Content Security Policy.
Set it up
- Enter the application's
collector_hashin the panel below, or open this page with?collector_hash=. Every snippet on the page then uses it. - Send the two headers on every HTML response of the site.
- Make sure every host that sends them is a site of that application, or a subdomain of one.
- Verify that a report arrives.
Your snippet
Opened from the app, these are filled in with your application's real values. Otherwise, paste them here and every snippet on this page updates.
Find both hashes in the app under Applications → ··· → IDs & hashes.
A report whose host is no site of the application is dropped, and a report never creates a site. www.shop.example counts for shop.example, notshop.example does not.
The headers
Reporting-Endpoints: fastmon-csp="https://fastmon.site/c/v/{collector_hash}"Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://js.payments.example; report-to fastmon-csp; report-uri https://fastmon.site/c/v/{collector_hash}The policy is an example. Keep your own directives and add report-to and report-uri. An application with a custom collector endpoint uses its own host instead of fastmon.site.
- On every HTML response. A policy covers the document that carries it, not the images or scripts it loads.
Reporting-Endpointsbeside the policy. It defines the groupfastmon-cspthatreport-tonames.Report-To, which NEL needs, is not required.- Both
report-toandreport-uri. Newer browsers usereport-toand ignorereport-uri, older ones send onlyreport-uri. Each violation arrives once. - The enforcing policy can report too. Add the same two directives to
Content-Security-Policy. Every report says whether it was blocked or only reported. - Leave out
'report-sample'. fastmon drops the code sample unread, see Privacy → CSP reports.
Examples
server { listen 443 ssl; server_name shop.example; add_header Reporting-Endpoints 'fastmon-csp="https://fastmon.site/c/v/{collector_hash}"' always; add_header Content-Security-Policy-Report-Only "default-src 'self'; report-to fastmon-csp; report-uri https://fastmon.site/c/v/{collector_hash}" always;}A location block with its own add_header inherits none from server, so repeat both lines there.
Verify
- The headers arrive. In the browser's network tab, check the document request for
Reporting-Endpointsand the policy header. - A violation shows. With a report-only policy that forbids something the page loads, the console prints a
[Report Only]message per violation. Chrome uploadsreport-toreports within about a minute, areport-urireport goes out at once. - The endpoint answers. Test both formats without a browser, with a registered site in place of
shop.example:
curl -i https://fastmon.site/c/v/{collector_hash} \-H 'Content-Type: application/reports+json' \--data '[{"age":0,"type":"csp-violation","url":"https://shop.example/","body":{"documentURL":"https://shop.example/","blockedURL":"https://cdn.example/x.js","effectiveDirective":"script-src-elem","disposition":"report","statusCode":200}}]'curl -i https://fastmon.site/c/v/{collector_hash} \-H 'Content-Type: application/csp-report' \--data '{"csp-report":{"document-uri":"https://shop.example/","blocked-uri":"inline","effective-directive":"script-src-elem","disposition":"report","status-code":200}}'The endpoint answers 204 whether it kept the report or dropped it. The Sites card on the Content Security Policy page shows each site's last report.
Traps
- A long policy fills the upload. One upload is capped at 128 KiB and every report carries the whole policy. A page that breaks a policy of several kilobytes dozens of times per load can exceed it, and the browser drops that upload.
- Shopify storefronts allow no custom response headers, so a Shopify shop cannot send a policy that reports to fastmon.
- Each application has its own hash. A report for a site of another application drops, even in the same organization.
- A hash rotation stops the reports silently. Put the new
collector_hashinto both directives. - A first-party proxy has to forward
/c/v/and theOPTIONSpreflight before areport-toupload. Alocation /c/block covers both.