Cross-Origin Resource Sharing (CORS) controls how browsers allow web pages from one origin to interact with resources from another origin. When configured securely, CORS prevents malicious websites from reading sensitive data from protected endpoints. When misconfigured, CORS allows attackers to bypass the browser’s same-origin policy, enabling them to steal user data, tokens, sessions, and even perform unauthorized actions.
CORS is one of the most misunderstood and misconfigured security controls in modern web applications. Many developers incorrectly trust Origin headers, enabling full cross-site attacks.
How CORS Works
Browsers enforce the same-origin policy (SOP). SOP blocks:
-
reading responses from another domain
-
accessing cookies from other domains
-
sending authenticated cross-site requests with readable output
CORS provides a controlled override to SOP.
When a browser sends a cross-origin request, it includes:
Origin: https://attacker.com
Server decides whether to allow the request based on CORS rules.
If server responds with:
Access-Control-Allow-Origin: https://attacker.com
and includes:
Access-Control-Allow-Credentials: true
then attacker.com can read the response and steal sensitive data.
Why CORS Is Dangerous
CORS misconfigurations allow attackers to:
-
steal authenticated user data
-
read private API responses
-
extract CSRF-protected resources
-
bypass session protections
-
perform advanced account takeover
-
escalate attacks using malicious websites
The browser’s protection collapses if developers trust malicious origins.
Common CORS Misconfigurations
1. Allowing All Origins
If server responds:
Access-Control-Allow-Origin: *
and does not allow credentials, the risk is low but still dangerous for public APIs.
If combined with:
Access-Control-Allow-Credentials: true
this configuration is invalid but some frameworks incorrectly allow it.
This exposes full authenticated data to ANY origin.
2. Reflecting the Origin Header
Server automatically reflects whatever the browser sends:
Request:
Origin: https://attacker.com
Response:
Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Credentials: true
This is a critical vulnerability.
Any attacker can host a malicious website and steal authenticated responses.
3. Wildcard Subdomain Trust
Access-Control-Allow-Origin: https://*.example.com
If any subdomain is vulnerable:
-
subdomain takeover
-
XSS
-
misconfigurations
attackers can escalate and steal data from main application.
4. Allowing Null Origin
Null origin occurs when:
-
sandboxed iframes
-
file:// protocol
-
data:// URLs
-
opaque origins
If server trusts null:
Access-Control-Allow-Origin: null
attackers can load the site in malicious sandboxed environments to read protected data.
5. Whitelisting HTTP Instead of HTTPS
Access-Control-Allow-Origin: http://example.com
If HTTPS is expected but HTTP is allowed:
-
downgrade attacks
-
MITM stealing cookies
-
malicious local scripts exploiting plain HTTP
6. Overly Permissive Allowed Methods
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Even if UI allows only GET/POST, CORS allows attackers to send privileged methods like DELETE or PUT.
7. Overly Permissive Allowed Headers
Access-Control-Allow-Headers: *
Attackers can inject custom headers:
-
X-Admin: true
-
Authorization: Bearer token
-
Internal override headers
Allows manipulation of internal APIs expecting privileged headers.
8. Allowing Credentials with Weak Controls
Access-Control-Allow-Credentials: true
If enabled, cookies (sessions) are sent cross-origin.
Combined with any permissive origin, attackers read authenticated data easily.
Practical CORS Exploitation
Step 1: Test for Reflection
Use a request with:
Origin: https://evil.com
If response returns:
Access-Control-Allow-Origin: https://evil.com
CORS bypass exists.
Step 2: Validate Credential Access
Send request:
Origin: https://evil.com
If response includes:
Access-Control-Allow-Credentials: true
attacker-controlled site can read authenticated data.
Step 3: Build Exploit Page
Attackers host:
<script>
fetch("https://target.com/api/user", {credentials:"include"})
.then(r => r.text())
.then(data => alert(data));
</script>
Victim visits attacker’s site.
Browser sends victim’s session cookies to target.
Attacker reads the sensitive data returned.
Step 4: Test Null Origin
Send:
Origin: null
If allowed:
Access-Control-Allow-Origin: null
use malicious iframe sandbox:
<iframe sandbox="allow-scripts" src="https://target.com"></iframe>
Step 5: Test Wildcard Subdomain
Try:
Origin: https://random.attacker-controlled-subdomain.example.com
If allowed, exploit via subdomain takeover or XSS.
Advanced CORS Attack Vectors
1. Exploiting Misconfigured Private APIs
Internal APIs trusting:
Access-Control-Allow-Origin: *
allow external attackers to read internal responses.
2. Combining CORS + XSS
XSS injects:
fetch("https://private-data", {credentials:"include"})
leaks sensitive data inside browser.
3. CORS + JSONP
If both enabled:
-
attackers bypass all restrictions
-
extract private JSON
-
circumvent CSRF protections
4. Using Malicious Service Workers
Malicious site installs service worker for:
https://example.com
when allowed by weak CORS and misconfigured scope.
This hijacks users permanently.
5. Abusing Access-Control-Expose-Headers
If server exposes sensitive headers:
Authorization
X-Internal-Token
Set-Cookie
Attackers read them via JS after CORS bypass.
Dangerous Patterns in Code
Automatically trusting Origin
Example vulnerable code:
res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
res.setHeader("Access-Control-Allow-Credentials", true);
This trusts any domain.
Permissive wildcard
Access-Control-Allow-Origin: *
plus:
Access-Control-Allow-Credentials: true
Browsers block it, but misconfigured servers often bypass the rule internally.
Using regex incorrectly
if (origin.includes("example.com"))
Attackers abuse:
evil-example.com
example.com.attacker.com
Practical CORS Testing Checklist
Test Reflection
Use random origin.
Test Credentials
Check if cookies sent cross-origin.
Test Null Origin
Send null.
Test Wildcard Subdomain
Try attacker subdomains.
Test Methods
Check if dangerous methods allowed.
Test Headers
Try privileged headers.
Test Internal API Access
Call non-public endpoints with attacker origin.
Test Error-Based Leaks
Some APIs leak data even when CORS blocks UI.
Why CORS Misconfigurations Happen
Causes include:
-
misunderstanding SOP
-
lazy “fix by allowing everything”
-
copying insecure examples from StackOverflow
-
trusting Origin header blindly
-
mixing development and production settings
-
misunderstanding credentials handling
Developers often over-permissively configure CORS for convenience.
Impact of CORS Misconfigurations
Misconfigured CORS leads to:
-
full account takeover
-
theft of user data
-
reading authenticated API responses
-
bypassing CSRF protections
-
leaking tokens and sensitive headers
-
accessing private endpoints
-
multi-user data exposure
-
full cross-origin compromise
Incorrect CORS effectively disables all browser-side protections.
Intel Dump
-
CORS governs cross-origin access; misconfiguration breaks same-origin policy.
-
Reflecting Origin or trusting wildcards is the most common vulnerability.
-
Credentialed requests with permissive CORS allow attackers to read authenticated responses.
-
Testing includes checking reflection, credentials, null origins, wildcard subdomains, and header/method permissiveness.
-
Allowing credentials with loose origins leads to full account compromise.
-
Impact includes data theft, privilege escalation, CSRF bypass, and total session compromise.