HackDefense Home
Kenneth Linzey

CSP – The how and why of a Content Security Policy

Recently we’ve recommended to more and more of our customers that they set up a Content Security Policy alongside the usual security headers. In this blog we dive deeper into that topic: where does this new standard originate from? Why would you like to use one? How do you set one up? And how does CSP relate to other, similar standards?

Where does this new standard originate from and why would you like to use one?

CSP is developed by the World Wide Web Consortium (W3C), the main international standards organization for the World Wide Web. CSP is a new standard that allows developers to define restrictions on the behaviour of a website or application. For example: from which external locations is it allowed to load scripts, stylesheets or images? Is the browser allowed to load the website in an iframe from a different website?

A well-adjusted CSP can prevent multiple attacks and vulnerabilites such as cross-site scripting (XSS) or clickjacking from happening.

How do you set up a CSP?

Webservers can add a special header named Content-Security-Policy to every response. For example, this website has set the following header:

Content-Security-Policy: default-src https://hackdefense.nl https://hackdefense.com; script-src 'none'; frame-ancestors 'none'; block-all-mixed-content; report-uri /csp-violations/;

What’s the meaning of the attributes?

It’s possible to define a lot of attributes within the CSP header. Please refer to this source for a complete and up-to-date overview of the attributes. We will highlight the most important ones:

  • default-src: this is the fallback for when other attributes have not been defined. Most of the times this attribute has the value self indicating that only resources from the website itself can be loaded.
  • script-src: restricts the locations external scripts can be loaded from. Value can be set to none if the website or application doesn’t use client side scripts.
  • img-src: restricts the locations images can be loaded from.
  • media-src: restricts the locations media (such as videos) can be loaded from.
  • object-src: restricts the locations plugins can be loaded from.
  • manifest-src: restricts the locations the manifest from the application can be loaded from.
  • frame-ancestors: this attribute restricts the locations that may load the website using frame, iframe, object, embed or applet elements. In due course frame-ancestors should replace the HTTP response header X-Frame-Options.
  • form-action: restricts the URLs that can be used as part of a <form> action. In other words, form-action restricts where the browser can send the data from completed forms. It’s important to note that form-action does not fallback on the default-src, so be sure to define this if your website or application uses form-elements.
  • Plugin-types: restricts the set of plug-ins which can be included by defining allowed MIME-types which are invoked via object, embed or applet.
  • Base-uri: Restricts the allowed URLs in the src arttribute of a base tag.

You can also use the CSP to enforce that resources can only ever be loaded using HTTPS by adding the https:// protocol to every value defined for the *-src attributes. This prevents resources from being loaded over non-encrypted HTTP connections. The same effect can be achieved by adding the attribute block-all-mixed-content.

CSP can also be used to restrict a couple of bad habits:

  • Unsigned inline Javascript in <script> blocks;
  • Unsigned inline CSS statements in <style> blocks;
  • Dynamic Javascript code evaluation with eval();
  • Dynamic CSS statements with the CSSStyleSheet.insertRule() method.

This enforces the best practice to have scripts and CSS in separate files referenced by HTML pages. If your site needs to allow it, the CSP can be set to do that using keywords like unsafe-eval and unsafe-inline.

How do you configure a CSP?

A CSP can be defined in several ways, for example in the web server configuration, or using PHP. We recommend to first apply a Content-Security-Policy-Report-Only header. This header will not block violations but only report them. This allows you to first define a CSP header, then calmly browse the website and handle CSP violations without impacting website functionality. One could use the following header as a starting point:

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri website.nl/api/post/csp-violations;

Every time a requested resource violates the CSP, the browser will make a POST request to the URL specified within the report-uri of the CSP including details of the violation. It’s important to keep track of these violations. On the one hand you would want to know when the CSP is unnecessarily blocking resources. On the other hand you would want to know when somebody is trying to inject resources into your website, perhaps an attacker or malicious user. If you already have a good idea what your CSP should look like, it’s also possible to generate a CSP using this website.

In the new draft for CSP level 3 report-uri is replaced with report-to, however report-to is only supported for the browsers Chrome and Microsoft Edge. We recommend to include both report-uri and report-to.

How does CSP relate to other standards?

SubResource Integrity (SRI) is a standard that complements CSP. SRI only allows trusted and familiar resources from third-party-providers to be loaded by the browser. More and more browsers are starting to support SRI. It works like this:

  • You calculate the hash of the third-party resource you would like to use on a webpage. You could use an online calculator or use the following one-liner on a Linux/​UNIX terminal:
openssl dgst -sha256 -binary FILENAME | openssl base64 -A
  • Then you add an extra atrribute to the third-party resource to be included on the webpage called integrity. The value of that attribute is the hash calculated in the first step. An example:
<script src="https://code.jquery.com/jquery-1.10.2.min.js" integrity="sha256-C6CB9UYIS9UJeqinPHWTHVqh/E1uhG5Twh+Y5qFQmYg=" crossorigin="anonymous"></script>
  • If the third-party resource now changes, the browser will refuse to load the resource because the hash no longer matches.

Using CSP you can enforce the use of SRI using the attribute require-sri-for with the values script orstyle.

If you have any questions about or need technical assistance securing your website or application using a Content Security Policy? You can find more information online at content​-security​-policy​.com, and you can always contact us – we’re happy to help!