Security

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

1

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.

2

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.

3

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.

4

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.

5

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.