The content security policy (CSP) is a special HTTP header used to mitigate certain types of attacks such as cross site scripting (XSS). Some engineers think the CSP is a magic bullet against vulnerabilities like XSS but if setup improperly, you could introduce misconfigurations which could allow attackers to completely bypass the CSP.
Content Security Policy (CSP)
The CSP header is fairly straight forward and there are only a few things you need to understand. First, the CSP header value is made up of directives separated with a semicolon “;” . You can think of these directives as policies which are applied to your site. A list of these directives can be found below, note these are not all of them but the most popular ones:
|default-src||This acts as a catchall for everything else.|
|style-src||Describes where we can load stylesheets from|
|img-src||Describes where we can load images from|
|connect-src||Applies to AJAX and WebSocket’s|
|font-src||Describes where we can load fonts from|
|object-src||Describes where we can load objects from (|
|media-src||Describes where we can load audio and video files from|
|frame-ancestors||Describes which sites can load this site in an iframe|
These directives are set to specific values which defines which resources can be loaded and from where. This source list can be found below:
|*||Load resources from anywhere.|
|‘self’||Can only load resources from same origin.|
|data:||Can only load resources from data schema (Base64)|
|something.example.com||Can only load resources from specified domain|
|https:||Can only load resources over HTTPS|
|‘unsafe-eval’||Allows dynamic code evaluation (eval() function)|
|‘sha256-‘||Can only load resources if it matches the hash|
|‘nonce-‘||Allows an inline script or CSS to execute if the script tag contains a nonce attribute matching the nonce specified in the CSP header.|
Now that you know about the structure of a CSP header let’s look at an example. As shown below you can see that the CSP is returned in the HTTP response header.
Github Content Security Policy
Basic CSP Bypass
There are quite a few ways to mess up your implementation of CSP. One of the easiest ways to misconfigure CSP is to use dangerous values when setting policies. For example, suppose you have the following CSP header:
default-src 'self' *
As you know the default-src policy acts a catch all policy. You also know that * acts as a wild card. So, this policy is basically saying allow any resources to be loaded. It’s the same thing as not having a CSP header! You should always look out for wildcard permissions.
Let’s look at another CSP header:
script-src 'unsafe-inline' 'unsafe-eval' 'self' data: https://www.google.com http://www.google-analytics.com/gtm/js https://*.gstatic.com/feedback/ https://accounts.google.com;
So far all of the techniques used to bypass CSP have been due to some misconfiguration or abusing legitimate features of CSP. There are also a few other techniques which can be used to bypass the CSP.
JSONP CSP Bypass
Google JSONP Endpoint
As you can see above, we have our alert function being displayed on the page.
Look at the following CSP header:
script-src https://www.google.com http://www.google-analytics.com/gtm/js https://*.gstatic.com/feedback/ https://accounts.google.com;
This would get blocked by the CSP.
CSP Injection Bypass.
The third type of CSP bypass is called CSP injection. This occurs when user supplied input is reflected in the CSP header. Suppose you have the following url:
If your input is reflected in the CSP header you should have something like this.
script-src something_vuln_csp; object-src 'none'; base-uri 'none'; require-trusted-types-for 'script'; report-uri https://csp.example.com;
This means we can control what value the script-src value is set to. We can easily bypass the CSP by setting this value to a domain we control.
The CSP is a header used to control where an application can load its resources from. This is often used to mitigate vulnerabilities such as XSS and clickjacking but if set up improperly it can be easy to bypass. Looking for things such as CSP injection or a vulnerable JSONP endpoint can be an easy way to bypass the CSP header. If the CSP was improperly set up you could use the CSP functionality against itself to bypass the CSP. For example, the use of ‘inline-scripts’ and wild cards is always dangerous when applied to the script-src policy.