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:
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 valueself
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 tonone
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 usingframe
,iframe
,object
,embed
orapplet
elements. In due courseframe-ancestors
should replace the HTTP response headerX-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 viaobject
,embed
orapplet
.Base-uri
: Restricts the allowed URLs in thesrc
arttribute of abase
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:
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:
- 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:
- 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!