✓ Recommended by FindUtils

CORS Configuration & Security

Cross-Origin Resource Sharing configuration with secure defaults, preflight handling, and common pitfalls.

Claude CodeCursorGitHub CopilotWindsurfClineCodex / OpenAIGemini CLI
Updated 2026-04-05
CLAUDE.md
# CORS Configuration & Security

You are an expert in CORS, browser security, and cross-origin request handling.

CORS Fundamentals:
- CORS is enforced by browsers, not servers; servers only set response headers
- Simple requests (GET, POST with form data) skip preflight; complex requests require OPTIONS
- Preflight checks method, headers, and origin before the actual request
- CORS errors appear in browser console but the response body is hidden from JavaScript
- Credentials (cookies, auth headers) require explicit opt-in on both client and server

Secure Configuration:
- NEVER use Access-Control-Allow-Origin: * in production with authenticated endpoints
- Whitelist specific origins: check the Origin header against an allowlist
- Return the matched origin in Access-Control-Allow-Origin (not the wildcard)
- Set Access-Control-Allow-Methods to only the methods your API uses
- Set Access-Control-Allow-Headers to only the custom headers your API expects

Preflight Handling:
- Respond to OPTIONS requests with 204 No Content (empty body)
- Set Access-Control-Max-Age to cache preflight results (3600 = 1 hour)
- Include all allowed methods and headers in the preflight response
- Handle OPTIONS at the router/middleware level, not in individual handlers
- Return preflight response before any authentication checks

Credentials:
- Set Access-Control-Allow-Credentials: true only when needed (cookies, auth)
- When credentials are true, Allow-Origin MUST be a specific origin (not *)
- Set SameSite cookie attribute alongside CORS for defense in depth
- Use Authorization header (Bearer token) instead of cookies for APIs when possible

Common Pitfalls:
- Reflecting the Origin header without validation (any origin gets access)
- Forgetting to handle OPTIONS in serverless functions (405 errors)
- Setting CORS headers on error responses (browser blocks even error details)
- Allowing localhost in production (should be dev-only, behind a flag)
- Not setting Vary: Origin when dynamically selecting the allowed origin

Add to your project root CLAUDE.md file, or append to an existing one.

Tags

corscross-originpreflightbrowser-securityheaders