CSP Reporting

Content Security Policy (CSP) helps browsers block unexpected scripts, frames, images, and other resources. Bugsink can receive browser-generated CSP violation reports and turn them into regular Bugsink issues.

This is useful when you are tightening a policy: run CSP in report-only mode first, collect the violations in Bugsink, fix the real ones, then switch to an enforcing policy when the noise is under control.

CSP reporting was introduced in Bugsink 2.2.3.

Setting it up

Bugsink accepts the classic CSP report-uri format at:

https://your-bugsink/api/<project_id>/security/?sentry_key=<project_sentry_key>

Use the numeric project ID and the project sentry key from the project DSN. For a DSN like:

https://publickey@your-bugsink.example.com/12

the CSP report endpoint is:

https://your-bugsink/api/12/security/?sentry_key=publickey

Start with a report-only header:

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri https://your-bugsink/api/12/security/?sentry_key=publickey

Once the reports look clean, move the policy to an enforcing header:

Content-Security-Policy: default-src 'self'; script-src 'self'; report-uri https://your-bugsink/api/12/security/?sentry_key=publickey

Browsers send reports directly. You do not need a JavaScript SDK for this endpoint.

How Bugsink handles reports

Each CSP report becomes a normal Bugsink event. It uses the same ingest authentication, quota checks, digestion, grouping, alerting, and retention path as other events.

Issues are grouped by:

effective-directive + blocked-uri

For example, repeated reports for script-src blocking https://evil.example.com/x.js become one issue titled:

CSP: blocked https://evil.example.com/x.js (script-src)

The original CSP report fields are stored on the event under:

contexts.csp

This usually includes fields such as document-uri, blocked-uri, violated-directive, effective-directive, original-policy, source-file, line-number, and column-number.

Limits and compatibility

Bugsink currently supports the browser report-uri format, where reports are posted with:

Content-Type: application/csp-report

The newer Reporting API / report-to format, which uses application/reports+json, is not covered by this endpoint.

CSP reports count against the project’s normal event quotas and retention limits. This is deliberate: a noisy policy can generate a lot of browser traffic, and those events should be managed like any other event stream.

The request body is capped by MAX_CSP_REPORT_SIZE, which defaults to 64 KiB. Real browser CSP reports are usually much smaller than that, so hitting the limit usually points to a broken client, a proxy issue, or abusive traffic.

Troubleshooting

If reports are not arriving, check the browser developer tools first. Browsers usually log failed CSP report delivery.

Common causes:

  • The endpoint uses the wrong project ID or sentry_key.
  • The Bugsink base URL is not reachable from the browser.
  • A reverse proxy strips the query string from the report URL.
  • A proxy rewrites the request Content-Type; Bugsink expects application/csp-report.
  • The policy is too noisy and the project is temporarily rate-limited.

If Bugsink returns 403, the project ID and sentry key do not match. If it returns 400, check the content type and JSON body. If it returns 413, the report body exceeded MAX_CSP_REPORT_SIZE.

Further reading