Content Security Policies#
A CSP:
- Is configured in the
Content-Security-Policyresponse header - Consists of multiple directives. Each directive allows one or more values.
For instance, the script-src directive defines where JavaScript can be loaded and executed from:
Content-Security-Policy: script-src 'self' https://benignsite.htbThis CSP instructs the browser to load JavaScript only from the same origin as the page itself and the external origin https://benignsite.htb. Therefore, if an attacker injects the following JavaScript code in an XSS payload, the victim’s browser will not load the script and thus not execute it:
<script src="https://exploitserver.htb/pwn.js"></script>However, the following scripts are allowed to load and execute:
<script src="/js/useful.js"></script>
<script src="https://benignsite.htb/main.js"></script>Furthermore, since the unsafe-inline value is not specified, it blocks all inline scripts (scripts inside HTML). Therefore, the following potential XSS payloads are all blocked and thus not executed:
<script>alert(1)</script>
<img src=x onerror=alert(1) />
<a href="javascript:alert(1)">click</a>Additionally, there are other common directives:
style-src: allowed origins for stylesheetsimg-src: allowed origins for imagesobject-src: allowed origins for objects such as<object>or<embed>connect-src: allowed origins for HTTP requests from scripts. For instance, usingXMLHttpRequestdefault-src: fallback value if a different directive is not explicitly set. For instance, if theimg-srcis not present in the CSP, the browser will use this value instead for imagesframe-ancestors: origins allowed to frame the page, for instance, in an<iframe>. This directive can be used to preventClickjackingattacksform-action: origins allowed for form submissions
For additional CSP directives, check out the list provided here.
Additional values for directives include:
*: All origins are allowed'none': No origins are allowed*.benignsite.htb: All subdomains ofbenignsite.htbare allowedunsafe-inline: Allow inline elementsunsafe-eval: Allow dynamic code evaluation, such as JavaScript’sevalfunctionsha256-407e1bf4a1472948aa7b15cafa752fcf8e90710833da8a59dd8ef8e7fe56f22d: Allow an element by hashnonce-S0meR4nd0mN0nC3: Allow an element by nonce
For additional CSP directive values, check out the list provided here.
Bypass Content Security Policies#
Suppose this is the CSP. It only allows js from the webapp or from google.com and every of its subdomains
Content-Security-policy: default-src 'self'; script-src 'self' https://*.google.com;JSONP#
JSONP refers to a technique that retrieves data across different origins by using script tags to retrieve data across origins, as they are exempt from the Same-Origin Policy
The basic of this attack is, we will fetch a API endpoint where it is allowed in the CSP, like https://accounts.google.com/o/oauth2/revoke
{
"error": "invalid_request",
"error_description": "Bad Request"
}If the API supports JSONP, it will read a GET parameter and adjust the response accordingly. This parameter is often called callback. Assume we call the endpoint https://accounts.google.com/o/oauth2/revoke?callback=alert(1). This results in the API sending the following response:
// API callback
alert(1)({
"error": {
"code": 400,
"message": "Invalid JSONP callback name: 'alert(1)'; only alphabet, number, '_', '$', '.', '[' and ']' are allowed.",
"status": "INVALID_ARGUMENT"
}
});So now we can just bypass CSP with this <script> tag
<script src="https://accounts.google.com/o/oauth2/revoke?callback=alert(1)"></script>Arbitrary File upload#
More on this on File Upload
We can just upload a js file like upload.pdf.js and call it
<script src="/uploads/upload.pdf.js"></script>