Skip to main content

Overly Permissive CORS

Overly permissive CORS allows any origin to read authenticated API responses, letting malicious sites steal a logged-in user's data. Use an explicit origin allowlist, avoid pairing credentials with wildcards, and add SameSite cookies and CSRF tokens.

Cross-Origin Resource Sharing (CORS) is a browser mechanism that lets a server declare which other origins may read its responses via JavaScript. Overly permissive CORS occurs when a server relaxes these rules too far — sending Access-Control-Allow-Origin: *, or reflecting whatever origin the request carries while also allowing credentials — turning the protection into a hole that lets attacker-controlled sites read sensitive responses.

Why It Happens

CORS errors are a frequent and frustrating roadblock during development. The fastest way to silence them is to allow all origins, so teams paste a wildcard and move on. Microservice and SPA setups multiply legitimate origins, and maintaining an exact list feels tedious. Developers may not understand that Allow-Origin: * combined with credentials, or origin reflection, exposes authenticated data rather than just public assets.

Why It Hurts

When an API serves authenticated, user-specific data and its CORS policy allows arbitrary origins to read responses with credentials, any website a logged-in user visits can issue requests in their session and read the results — stealing personal data, tokens, or API keys. Reflecting the Origin header back with Allow-Credentials: true is the same vulnerability dressed up to look restrictive. Broad CORS also amplifies CSRF and undermines the browser's same-origin protections that the rest of the security model depends on.

Warning Signs

  • Responses include Access-Control-Allow-Origin: * on endpoints that return private data.
  • The server echoes the request's Origin into the allow-origin header.
  • Access-Control-Allow-Credentials: true is set alongside a permissive origin policy.
  • Allowed methods and headers are set to wildcards without need.

Better Alternatives

Maintain an explicit allowlist of trusted origins and reflect only those; never combine wildcards or arbitrary reflection with credentials. Keep CORS as narrow as the application requires — list only the methods and headers actually used. For cookie-based auth, set cookies to SameSite=Lax or Strict so they are not sent on hostile cross-site requests, and pair state-changing endpoints with anti-CSRF tokens. Treat truly public, non-credentialed assets differently from authenticated APIs.

How to Refactor Out of It

  1. Inventory every endpoint's CORS configuration and classify each as public or authenticated.
  2. For authenticated APIs, replace wildcards and reflection with a vetted origin allowlist.
  3. Remove Allow-Credentials: true unless credentials are genuinely required, and never pair it with *.
  4. Restrict allowed methods and headers to what the client actually uses.
  5. Add SameSite cookie attributes and CSRF tokens as additional layers.
  6. Test from an unlisted origin to confirm the browser blocks reading the response.