Last updated at Tue, 14 May 2019 19:34:02 GMT

Browser makers began implementing the Content Security Policy, or CSP specification back in 2011. Since then, many development teams and organizations have adopted CSP wholeheartedly to try and thwart XSS attacks, but it seems the effort may have been wasted for the majority.

To analyze recent CSP adoption, Google performed an Internet-wide analysis [1] on a search engine corpus of approximately 100 billion pages from over 1 billion hostnames; the result covers CSP deployments on 1,680,867 hosts with 26,011 unique CSP policies. From the results, researchers found:

  • 75.81% of policies allow attackers to bypass CSP.
  • 94.68% of policies that attempt to limit script execution are ineffective
  • 99.34% of policies offer no benefit against XSS

So, even though CSP adoption is becoming more mainstream, it seems that folks just aren’t getting it right.


As more and more organizations implement CSP and devote development efforts to it, it’s essential to understand how to apply a proper policy and how to ensure your application is tested and appropriately protected.

Over the past few years, a few beneficial (open source) tooling projects around CSP creation and deployment have been created [2], but those humble efforts do not address the massive gap between specification version fragmentation and configuration based on real application traffic. Not to mention, managing those configurations across tens or hundreds of applications.

Because of these ongoing operational issues around keeping pace with the evolution of CSP and securing web applications, tCell has created a unique enterprise solution around CSP creation and management.

First, developers now have the ability to understand the policy being delivered to the browser, visually. By default, tCell uses a default CSP that reports everything back to the tCell console. Policy enforcement starts out in Report Only mode so that you can begin to fine-tune things until you’re ready to start blocking unknown behavior.
Screen Shot 2017-11-08 at 11.01.35 AM.png
Next, The following view gives a high-level summary of the application-wide CSP configuration along with data on events that have occurred across the app. This view also allows application owners to manually add, exclude and ignore directive and URI patterns.
Screen Shot 2017-11-08 at 11.03.02 AM.png
The CSP Violations (XSS) view will give insight into which events should be added to the CSP and which ones are malicious.
Screen Shot 2017-11-08 at 11.08.36 AM.png
From here, developers can drill into Event Groups and understand directives, domains, and other valuable data around violations in the CSP.
Screen Shot 2017-11-14 at 4.43.18 PM.png
Simply put, CSP can and will protect your application from XSS attacks. But without the proper tooling and validation framework around CSP enforcement, we can see from the Google research paper that many who are implementing CSP still may be doing it wrong – only because the policy cannot be validated or adequately tested.

All of the information above, along with step by step instructions on hardening your applications can be found in the tCell Documentation.

[1] CSP Is Dead, Long Live CSP! On the Insecurity of Whitelists and the Future of Content Security Policy

[2] Open Source CSP Tooling

  • Salvation
    Parse Content Security Policy headers, warn about policy errors, safely manipulate, render, and optimise policies
  • Helmetjs
    There are a lot of inconsistencies in how browsers implement CSP. Helmet looks at the user-agent of the browser and sets the appropriate header and value for that browser. If no user-agent is matched, it will set all the headers with the 2.0 spec.
  • CSP Inline Agent
    An initial report will be sent with current scripts, then any new scripts or event-handlers are added to the DOM will be sent as additional events. Events are wrapped in a JSON structure that will also communicate a request id, session id (localstorage), documentUri, and referrer.
  • CSP Builder
    Build Content-Security-Policy headers from a JSON file (or build them programmatically)