CORS · How to Configure It Without Breaking Things
CORS (Cross-Origin Resource Sharing) is a browser-enforced protocol that decides which origins can read responses from your API. It's not a firewall · it doesn't stop requests, only response reads. The common mistake is treating `*` as safe or as unsafe · it's neither. It's safe for public data, unsafe with credentials.
Common misconfigurations
- `Allow-Origin: *` on authenticated endpoints · With `Allow-Credentials: true`, browsers reject `*`. But some servers dynamically echo the caller's origin · effectively unbounded.
- Echoing `Origin` blindly · `Access-Control-Allow-Origin: <caller's Origin>` with credentials on = any site can read authenticated responses. Whitelist instead.
- Preflight caching too long · `Access-Control-Max-Age: 86400` is fine. But if you change CORS mid-flight, browsers won't re-check for a day.
- CORS as authorization · CORS is a browser feature. `curl` and server-to-server calls ignore it. Never rely on it for auth.
Frequently asked
Is `Access-Control-Allow-Origin: *` insecure?
Only when combined with credentials or when the endpoint returns user data. For public assets, it's fine.
Does CORS block API abuse?
No · it only blocks browsers reading cross-origin responses. Rate limits and auth block abuse.
How do I whitelist multiple origins?
Compare the incoming `Origin` header against an allow-list, then echo it back. Never `*` when credentials are involved.
Scan your app →