Skip to main content

Security

CORS and Cookie Security Checklist for Production Apps

CORS and cookies sit on the browser boundary where frontend convenience can become account takeover risk. Most dangerous configurations look harmless in local development: wildcard origins, overly broad cookie domains, missing SameSite, missing Secure, and preflight responses that approve more methods or headers than the API actually needs.

Try our CORS Tester

Separate public APIs from credentialed browser APIs

A public read-only endpoint can often use broad CORS safely. A credentialed API cannot. If the browser sends cookies or Authorization headers the server must validate the Origin against an explicit allowlist return that exact origin and include Access-Control-Allow-Credentials only when the origin is trusted.

Never combine wildcard origins with credentials

Access-Control-Allow-Origin: * is incompatible with credentialed requests and should not appear on authenticated browser APIs. Reflecting any incoming Origin is just a wildcard with extra steps. Use an explicit list of production staging and preview origins and keep local development origins out of production config.

Constrain methods, headers, and preflight cache

Preflight should approve only the methods and request headers the endpoint needs. A login route probably does not need PUT DELETE or arbitrary custom headers. Cache preflight responses with Access-Control-Max-Age only after the policy is stable; long cache times make emergency policy changes slower to reach browsers.

Set cookie flags deliberately

Session cookies should normally use Secure HttpOnly and SameSite=Lax or Strict. SameSite=None is required for some cross-site embedded or third-party flows but it also requires Secure and should be treated as a special case. HttpOnly prevents client-side scripts from reading the cookie; Secure prevents transmission over plain HTTP.

Scope cookie domain and path tightly

A broad Domain=.example.com cookie is shared with every subdomain including legacy apps and marketing microsites. Prefer host-only cookies unless multiple trusted subdomains truly need the same session. Use Path to reduce accidental exposure but do not treat Path as a strong security boundary by itself.

Test the real browser request

CORS is enforced by browsers not by curl. Verify OPTIONS preflight actual request headers credential behavior blocked origins and error messages from a browser or browser-accurate tool. Test both allowed and disallowed origins; a policy that only gets tested from the happy-path frontend can still be wide open.

Monitor drift after deployment

CORS and Set-Cookie headers often drift during CDN auth provider reverse proxy and environment changes. Add header checks to release smoke tests and scheduled audits. Treat a sudden wildcard origin missing Secure flag or unexpected SameSite=None as a security regression not a cosmetic warning.

FAQ

Is CORS an authentication mechanism?+

No. CORS is a browser enforcement boundary. APIs still need real authentication and authorization on every request because non-browser clients can call the endpoint directly.

When is SameSite=None appropriate?+

Use SameSite=None only when a legitimate cross-site browser flow requires cookies such as an embedded app or third-party identity flow. It must be paired with Secure and reviewed as a deliberate exception.

Want to verify your setup?

Run the check now