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

Cross-Origin Resource Sharing (CORS) – Overview

Lab Levels

Jump directly to the lab writeups:

Introduction

Cross-Origin Resource Sharing (CORS) is a security mechanism implemented by browsers to control how web applications from one origin can interact with resources on a different origin using specific HTTP headers.


Same-Origin Policy (SOP)

The Same-Origin Policy (SOP) is a fundamental browser security concept that restricts how documents or scripts loaded from one origin can interact with resources from another origin.

SOP Example 1
Figure: Example of same-origin request

SOP Example 2
Figure: Table view of SOP restrictions between origins

SOP Tree Diagram
Figure: Example of cross-origin request being blocked by SOP


Key CORS Headers

Access-Control-Allow-Origin

Specifies which origins are permitted to access the resource.

Misconfigured servers that trust null may be vulnerable to restricted-context attacks.

ACAO Example 1
Figure: Example of Access-Control-Allow-Origin with a specific origin

ACAO Example 2
Figure: Example of Access-Control-Allow-Origin using a wildcard or null


Access-Control-Allow-Credentials

Indicates whether the response can be exposed when the request’s credentials mode is include.

ACAC Example 1
Figure: Correct CORS configuration with credentials

⚠️ Important: Access-Control-Allow-Origin: * cannot be used with Access-Control-Allow-Credentials: true — browsers will block the request.

ACAC Example 2
Figure: Incorrect CORS configuration using wildcard with credentials


CORS Misconfiguration Risks

Misconfigurations in CORS can lead to serious security issues such as:


JavaScript Templates to Test for CORS Vulnerabilities

These templates can be used in a browser console to test whether a cross-origin endpoint is accessible and leaks sensitive information.

Method 1

var req = new XMLHttpRequest();
req.onload = function () {
    alert(this.responseText);
};
req.open('GET', 'https://target-site.com/endpoint', true);
req.withCredentials = true;
req.send(null);

Method 2

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
        alert(xhr.responseText);
    }
};
xhr.open('GET', 'http://targetapp/api/v1/user', true);
xhr.withCredentials = true;
xhr.send(null);

These scripts attempt to retrieve sensitive information from the target site using the victim’s authenticated session.


References