Content Security Policy (CSP)

A Content Security Policy (CSP) is a mechanism provided to web developers to control resources (such as javascript, css, images and video) that the browser is allowed to load for a website.

Your Content Security Policy is delivered in the form of an HTTP response header along with the page to the browser. The browser will then evaluate your policy and enforce it for the content on the page.

Switch CSP reporting to Raygun

If you're already using a Content Security Policy on your website then read how to Switch your CSP reporting to Raygun


When getting started with CSP reporting, we recommend you configure a report only header that will report policy violations but not enforce the policy. This will allow you to test and refine your policy before setting it to be enforced by the browser.

Deprecation warning

The report-uri feature of CSP has been depracated and replaced with the report-to directive, however not all browsers yet support this. Because of this, we recommend setting both report-uri and report-to as shown in the examples throughout this documentation. Take care to note that the legacy report-uri points to the Raygun /reports-csp endpoint, whereas report-to uses the Raygun /reports endpoint.

Ensure you have the Report-To header defined as described in setting up the Reporting API. The code examples in this document rely on there being a named endpoint called "raygun" defined in the Report-To header.

Add an HTTP response header to your web application with the following policy configured to report only. This policy will generate a lot of reports but it will help you identify the resources being loaded by your website.

Content-Security-Policy-Report-Only: default-src 'none'; form-action 'none'; frame-ancestors 'none';
  report-uri https://report-to-api.raygun.com/reports-csp?apikey=<YOUR-API-KEY>
  report-to raygun

Now that you are receiving reports from your policy, start refining your policy to allow the resources that you are expecting to be loaded.

For example if your site uses a lot of inline code that makes it hard to fix but you still want to ensure resources are loaded only over HTTPS and disable old plugins, then you could look at apply a policy like this:

Content-Security-Policy-Report-Only: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'
  report-uri https://report-to-api.raygun.com/reports-csp?apikey=<YOUR-API-KEY>
  report-to raygun

When you are finally happy with the reports you are receiving and that they are not reporting anything you would want to be loaded, then change the header name from Content-Security-Policy-Report-Only to Content-Security-Policy.


If you already have a Content Security Policy defined, then switching it to Raygun is as simple as changing the report-uri property and your report-to group endpoint depending on your configuration. Due to the deprecation warning above, we recommend setting both the report-uri and report-to directives.

Here's an example of a CSP report set up that currently does not send to the Raygun endpoints, followed by an updated version that does send to Raygun.

# Existing policy
Content-Security-Policy: <policy-directive>;
  report-uri https://example.com/csp-reports
  report-to csp-endpoint
  
# Existing group
Report-To: {
  "group": "csp-endpoint",
  "max_age": 10886400,
  "endpoints": [
    { "url": "https://example.com/reports" }
  ]
}

In the updated set up below, the report-uri now gets set to the Raygun /reports-csp endpoint and the Report-To group gets updated to use the Raygun /reports endpoint. Use the API key of the application in Raygun where you'd like the reports to be sent to.

# Updated policy
Content-Security-Policy: <policy-directive>;
  report-uri https://report-to-api.raygun.com/reports-csp?apikey=<YOUR-API-KEY>
  report-to csp-endpoint
  
# Updated group
Report-To: {
  "group": "csp-endpoint",
  "max_age": 10886400,
  "endpoints": [
    { "url": "https://report-to-api.raygun.com/reports?apikey=<YOUR-API-KEY>" }
  ]
}

Providing user information will allow your Raygun dashboard to display the number of unique users that each CSP violation has affected. This is a huge help with prioritising issues to solve that have the largest impact. You can provide whatever user information that will help you solve issues, but make sure to abide by any privacy policies that your company follows. At the very least, providing a unique guid will allow you to see the number of users that are affected by each policy violation. If available, you could provide an ID that is meaningful to you such as a database ID. If you are able to provide a name and contact details, you'd be able to contact customers to let them know that issues they've encountered are being worked on, or have been solved.

Since there is no way to inject data into the CSP report payload you can provide user information via the URL that is used to report the CSP violations to Raygun. The user querystring parameter can be set to a URL encoded JSON object that represents a user.

# A user object like this would be URL encoded into the report uri
# {"identifier":"123456789","isAnonymous":false}

Content-Security-Policy: ...;
  report-uri https://report-to-api.raygun.com/reports-csp
    ?apikey=<YOUR-API-KEY>
    &user=%7B%22identifier%22%3A%22123456789%22%2C%22isAnonymous%22%3Afalse%7D
  report-to raygun

Here are all the available user properties:

  • identifier is the unique identifier from your system for this user.
  • isAnonymous is a flag indicating whether the user is logged in (or identifiable) or if they are anonymous. An anonymous user can still have a unique identifier.
  • email The user's email address. If you use email addresses to identify your users, feel free to set the identifier to their email and leave this blank. We will use the identifier as the email address if it looks like one, and if no email address is specified in this field.
  • fullName The user's full name.
  • firstName The user's first (or preferred) name.
  • uuid A device identifier. Could be used to identify users across devices, or machines that are breaking for many users.

When a CSP violation is recorded we automatically tag the report with the violating directive, blocked host, and a csp tag. If the blocked host is not a URL then we will tag it with "chrome-extension", "blob", "about", "data" or "eval" depending on the CSP report data.

You can add additional tags to CSP reports by appending a tags querystring parameter to the report uri that represents a URL encoded JSON string array.

# Tags can be URL encoded into the report uri
# ["tag1","tag2"]

Content-Security-Policy: ...;
  report-uri https://report-to-api.raygun.com/reports-csp
    ?apikey=<YOUR-API-KEY>
    &tags=%5B%22tag1%22%2C%22tag2%22%5D
  report-to raygun

You can insert key-value custom data to your CSP reports by appending a customData querystring parameter to the report uri that represents a URL encoded JSON object.

# Custom data can be URL encoded into the report uri
# {"area": "51"}

Content-Security-Policy: ...;
  report-uri https://report-to-api.raygun.com/reports-csp
    ?apikey=<YOUR-API-KEY>
    &customData=%7B%22area%22%3A%20%2251%22%7D
  report-to raygun

The version number of your application can be appended to any CSP reports by appending a version querystring parameter to the report uri that represents a URL encoded string.

# A version can be URL encoded into the report uri

Content-Security-Policy: ...;
  report-uri https://report-to-api.raygun.com/reports-csp
    ?apikey=<YOUR-API-KEY>
    &version=1.0.0.1
  report-to raygun

CSP reports are processed in Raygun as a Crash Report meaning you can use all the same features of Crash Reporting with your CSP reporting.

For example you can use the inbound filters to filter out CSP reports tagged with chrome-extension to discard reports generated by Chrome extensions. If you still want to collect the reports but don't want to be notified about them then use error statuses and set it to permanently ignored.

To aid you in finding relevant information you can use the filtering or search functions, or export your data to analyze it in a 3rd party tool.