CORS (Cross-Origin Resource Sharing) is the browser mechanism that controls which websites can make requests to your API. Get it right, and it's a powerful defense against cross-origin attacks. Get it wrong, and your API is accessible to every malicious website on the internet.
We find CORS misconfigurations in over 65% of web application audits. Most teams don't fully understand what CORS does — or what happens when it's misconfigured.
How CORS Works (in 30 Seconds)
Browser Request
JavaScript on attacker.com tries to fetch data from your-api.com
Browser Check
Browser sends an Origin header. Your API responds with Access-Control-Allow-Origin.
Decision
If the origin is allowed, the browser gives the response to the JavaScript. If not, the browser blocks it.
CORS is enforced by the browser, not the server. The server tells the browser which origins to trust via response headers. A misconfigured CORS policy means the server is telling browsers to trust origins that shouldn't be trusted.
The Misconfigurations
1. Reflecting Any Origin
highThe most common and most dangerous misconfiguration:
Server reflects the Origin header
The API reads the Origin header from the request and echoes it back as Access-Control-Allow-Origin — accepting ANY origin
Combined with credentials
If Access-Control-Allow-Credentials: true is also set, authenticated requests from any origin are accepted — including the user's cookies
Attacker's website reads your API
A malicious website makes authenticated requests to your API on behalf of the logged-in user and reads the responses — extracting personal data, account details, or performing actions
🛑The Wildcard Trap
Setting Access-Control-Allow-Origin: * seems dangerous but is actually less harmful — browsers refuse to send credentials with wildcard CORS. The real danger is reflecting the exact origin with Allow-Credentials: true, because it accepts every origin AND includes cookies.
2. Null Origin Allowed
highSome CORS configurations trust the null origin:
Null Origin Attack
When Origin is null
Sandboxed iframes, local file:// pages, and certain redirect flows send Origin: null. If your API trusts null, an attacker can use a sandboxed iframe to make credentialed requests from null origin.
The attack
Attacker page contains: iframe sandbox="allow-scripts" with JavaScript that fetches your API. The request has Origin: null. Your API responds with Access-Control-Allow-Origin: null — and the browser allows it.
3. Regex Bypass in Origin Validation
mediumMany teams implement origin validation with regex — and get it wrong:
Regex Bypass Examples
Suffix matching
Regex: /example.com$/ — allows evil-example.com, not just example.com. Missing the anchor for the start of the domain.
Unescaped dots
Regex: /example.com/ — the dot matches any character. exampleXcom.attacker.com passes the check.
Subdomain wildcard
Regex: /.*.example.com/ — allows anything.example.com. If the attacker achieves a subdomain takeover, they bypass CORS.
As we covered in Subdomain Takeover, subdomain takeover combined with wildcard CORS policies creates a direct path to data theft.
4. Pre-Flight Bypass
mediumBrowsers only send pre-flight (OPTIONS) requests for "non-simple" requests. Simple requests (GET with standard headers) skip the pre-flight. If your CORS check only runs on OPTIONS responses, simple requests bypass it entirely.
The Impact
What Attackers Can Do
- •Read authenticated API responses (personal data, account info)
- •Perform actions on behalf of the user (CSRF via JavaScript)
- •Extract CSRF tokens and bypass CSRF protections
- •Access internal APIs that rely on CORS for protection
What They Can't Do (with CORS alone)
- •Bypass server-side authentication (CORS is browser-only)
- •Access APIs that aren't vulnerable to CORS misconfiguration
- •Exploit CORS without getting the user to visit a malicious page
The Fix
Explicit Allowlist
Maintain a strict list of allowed origins. Check against exact matches, not regex.
Never Reflect
Never echo the Origin header back as-is. Always check against your allowlist first.
Reject Null
Never allow the null origin. There's no legitimate reason to trust it in production.
Minimize Credentials
Only set Allow-Credentials: true when absolutely necessary, and only for specific trusted origins.
💡The Simple Rule
If your API needs to accept credentials (cookies, auth headers) from browser JavaScript: maintain an explicit allowlist of trusted origins. Check each request's Origin against the list. If it matches, reflect that specific origin. If not, don't set any CORS headers. Never use wildcards with credentials. Never trust null.
As we covered in Security Headers: The Complete Implementation Guide, CORS headers are part of a broader security header strategy. And in API Security: The Blind Spots Most Teams Miss, we noted that CORS misconfiguration is one of the most common API security issues.
How We Test CORS
Our Web Security Auditor automatically tests CORS on every endpoint:
- Origin reflection — Send requests with arbitrary origins and check if they're reflected
- Null origin — Test if the null origin is trusted
- Subdomain variations — Test with subdomains, similar domain names, and prefix/suffix matches
- Credential interaction — Verify that Allow-Credentials isn't combined with permissive origin policies
- Pre-flight bypass — Test simple requests that skip CORS pre-flight checks
For complex multi-origin architectures, our expert review validates the full CORS policy across all API endpoints and subdomains.
CORS misconfigurations are one of the easiest vulnerabilities to find and fix — yet one of the most commonly missed. Our Web Security Auditor checks every endpoint. Start a scan and see your CORS posture in minutes.