Mitigate XSS Attacks with Content Security Policy

As of this commit, we’ve turned off CSP violations reports by default because the vast majority of the reported violations are false positives.

To illustrate this, here is a screenshot of logs from a site running Discourse with CSP enabled and reporting enabled (filtered using “CSP Violation”):

All of the reported violations are not related to the site’s code:

  • violations with ‘minisrclink.cool’ or ‘proxdev.cool’ in the URL have nothing to do with Discourse, they’re likely coming from a browser extension
  • the Google Analytics violation reports are also not legitimate. They are triggered by Firefox in privacy mode, or Firefox with a privacy extension enabled (like DuckDuckGo Privacy Essentials).
  • Violations with ‘inline’, ‘data’ or ‘about’ are triggered by extensions as well. It’s not shown in the screenshot above, but these violations have some more details in the env tab of the log. In there, under script-sample, some of these violations had code like BlockAdBlock or window.klTabId_kis or AG_onLoad, which come from the AdBlock, Kaspersky, and AdGuard extensions, respectively. (I found this repo: https://github.com/nico3333fr/CSP-useful/blob/master/csp-wtf/README.md very useful in helping explain some of these reports.) Some of these violations will have safari-extension or user-script in the source-file variable (again, in env), so that points to Safari extensions as the culprit for the violation.

In other words, there’s a lot of noise in CSP violation reports, so it’s not useful to log them at all times. They might be helpful while you are configuring CSP, but the reporting should be off during the normal operation of a site.

A few final notes: if you site is using a tag manager (like Google Tag Manager or Segment) you need to load the site in your browser, and carefully examine the violations in the console. These tools load third-party scripts from third-party domains and/or inline scripts so you need to carefully whitelist each of them using the source URL or the hash of the inline script (Chrome usefully includes the hash of inline scripts in the console error statement).

If your site uses an advertising service (like Google Ad Manager, Adsense, etc.) you probably will have to use a very permissive policy:

In the screenshot above, the policy allows any script from a https: source and any inline script. (In the future, this might be replaced by the strict-dynamic keyword, but as of this writing, strict-dynamic isn’t supported by Safari or Edge.)

24 Likes