CORS Misconfigurations That Silently Expose Your API to Any Origin
You set up CORS headers so your frontend can talk to your API, tested that requests work, and moved on. That's exactly how most CORS misconfigurations slip into production β they look correct until an attacker reads your users' private data from a page they control.
CORS mistakes are different from most vulnerabilities: they don't generate errors in your logs, they don't crash anything, and they often pass code review because the intent seems reasonable. Understanding the precise patterns that create exposure is the only way to catch them.
What CORS Is Actually Doing (and What It Is Not)
Browsers enforce the Same-Origin Policy (SOP): a script running on https://evil.com cannot read the response to a fetch request sent to https://yourapi.com. CORS is a controlled relaxation of that rule. When your server sends Access-Control-Allow-Origin: https://yourfrontend.com, it tells the browser that one specific origin is allowed to read the response.
Two things are critical to understand before we go further:
- CORS controls whether a browser script can read a response. It does not prevent the request from being sent. Your server still processes the request; CORS only gatekeeps the client's ability to see the result.
- CORS headers are enforced by the browser. A server-side script, curl, or Postman ignores them entirely. If your API relies on CORS as its only protection, any non-browser client bypasses it completely.
What You'll Learn
- Why wildcard origins combined with credentials are dangerous even when browsers block them by default
- How reflecting the request's
Originheader without validation hands attackers carte blanche - The
nullorigin loophole and why it's exploitable from sandboxed iframes - How loose regex patterns let attackers register look-alike domains
- Concrete header configurations that fix each class of problem
The Wildcard + Credentials Combination
The most well-known CORS rule is that you cannot combine Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true. Browsers will block the response if you try. So teams that need credentialed cross-origin requests (cookies, HTTP auth) switch to reflecting the origin dynamically β and that is where things go wrong.
But even a plain wildcard without credentials creates real risk for APIs that rely on network-level access control. If your API is internal and expects only intranet clients, a wildcard CORS policy lets a malicious external page trigger requests from an internal user's browser and read the responses.
# Dangerous: wildcard on an internal-facing API
Access-Control-Allow-Origin: *
# Safe for truly public, read-only, unauthenticated data only
Access-Control-Allow-Origin: *Wildcard is only safe when the data is genuinely public, requires no authentication, and carries no user-specific content. If any of those conditions are false, use an explicit allowlist.
Reflecting the Request Origin Without Validation
This is the most dangerous pattern in the wild. Some servers are configured to take whatever value appears in the incoming Origin header and echo it back as Access-Control-Allow-Origin. The intent is usually
Frequently Asked Questions
Can a CORS misconfiguration be exploited without the user doing anything suspicious?
Yes. The attack requires only that a victim visits the attacker's page while logged into your service. The attacker's JavaScript silently fetches your API using the victim's credentials, and a permissive CORS policy allows the attacker's script to read the response.
Does setting Access-Control-Allow-Origin to a wildcard protect against credentialed requests?
Browsers block credentialed requests (those with cookies or HTTP auth) when the server returns a wildcard origin. However, attackers can still exploit a wildcard to read non-credentialed responses, which matters for internal APIs or any API that relies on network-level access controls rather than per-request authentication.
How do I test whether my API has a CORS misconfiguration?
Send an OPTIONS preflight request using curl with a crafted Origin header set to an unrecognized domain and inspect the Access-Control-Allow-Origin value in the response. If the server echoes back your fake origin or returns a wildcard, the policy is misconfigured.
Is it safe to allow CORS from all subdomains of my own domain?
No. Trusting all subdomains means a compromised or abandoned subdomain instantly becomes a trusted CORS origin. Use an explicit allowlist of specific subdomains rather than a wildcard or suffix match.
Does a correct CORS policy protect my API from CSRF attacks?
Not completely. CORS controls whether a browser script can read a cross-origin response, but simple requests such as form posts can still be triggered cross-origin without a preflight. You need a separate CSRF mitigation strategy, such as requiring custom headers or using the SameSite cookie attribute.
π€ Share this article
Sign in to saveRelated Articles
Comments (0)
No comments yet. Be the first!