CORS Best Practices
CORS errors are one of the most common sources of confused debugging, largely because the fix people reach for first — disabling CORS entirely, or setting Access-Control-Allow-Origin to '*' everywhere — trades a confusing error for a real security gap.
Last updated 2026-09-08
Whitelist specific origins instead of using a wildcard for anything credentialed
Access-Control-Allow-Origin: * is fine for a genuinely public, unauthenticated API, but browsers block wildcard origins entirely when credentials (cookies, auth headers) are involved. List exact allowed origins explicitly for any endpoint that handles authenticated requests.
Never reflect the request's Origin header back unconditionally
Dynamically setting Access-Control-Allow-Origin to whatever Origin the request sent, without checking it against an allowlist, effectively disables the origin restriction entirely — any site can now make credentialed requests to your API.
Understand what a CORS preflight actually checks
For non-simple requests (custom headers, methods other than GET/POST, or a JSON content-type), the browser sends an OPTIONS preflight first. Your server needs to respond to OPTIONS correctly, not just the actual request method, or the real request never gets sent at all.
Set Access-Control-Allow-Credentials explicitly when cookies are involved
If your API relies on cookies for authentication across origins, both the server (via this header) and the client (via credentials: 'include' in fetch) need to explicitly opt in — omitting either side silently drops the cookie.
Keep allowed headers and methods minimal
Access-Control-Allow-Headers and Access-Control-Allow-Methods should list only what your API actually needs, not a broad catch-all — a minimal, explicit configuration is easier to reason about and audit.
Common Mistakes to Avoid
- ⚠Setting Access-Control-Allow-Origin: * on an endpoint that also handles authenticated/credentialed requests
- ⚠Reflecting the Origin header back unconditionally instead of checking it against an allowlist
- ⚠Not handling the OPTIONS preflight request correctly, so the actual request never fires
- ⚠Forgetting credentials: 'include' on the client side even after configuring the server correctly
- ⚠Treating a CORS error as a server-availability problem rather than a browser-enforced policy issue
Frequently Asked Questions
Is CORS a server-side or browser-side restriction?
Browser-side — CORS is enforced by the browser reading the server's response headers. A tool like curl or Postman making the same request won't be blocked, since the restriction only applies to browser-initiated cross-origin requests.
Can I fix a CORS error by adding a proxy?
Yes — routing the request through your own backend (which isn't subject to browser CORS restrictions when talking server-to-server) is a legitimate, common workaround, particularly for third-party APIs you don't control.