Understanding Access-Control-Allow-Origin Header
The Access-Control-Allow-Origin header is a critical security mechanism that controls how resources on a server can be shared with web pages from different origins. As a core component of Cross-Origin Resource Sharing (CORS), it enables servers to specify which external domains may access their resources while preventing unauthorized cross-origin requests. Browsers enforce this policy to protect users from security risks like cross-site request forgery (CSRF) and data leaks.
How It Works
When a web application makes a cross-origin request—for example, fetching data from api.example.com while hosted on app.example.com—the browser first checks the server's CORS policy. The server responds with the Access-Control-Allow-Origin header to indicate whether the requesting origin is permitted to access the resource.
Basic flow:
- Client makes a request from
https://app.example.comtohttps://api.example.com - Server responds with
Access-Control-Allow-Originheader - Browser allows or blocks the response based on the header value
Configuration Options
Single Origin
Restricts access to one specific domain. This is the most secure option for sensitive resources.
Access-Control-Allow-Origin: https://trusted-site.com
When to use: Single trusted frontend application accessing protected resources.
Important: If the request includes credentials (cookies, HTTP authentication), the origin must be explicitly specified—wildcards are not allowed.
Multiple Origins
Allows access from a predefined list of domains. The server must dynamically validate the Origin header against an allowlist.
const allowedOrigins = ["https://app1.com", "https://app2.com"];
const requestOrigin = req.headers.origin;
if (allowedOrigins.includes(requestOrigin)) {
res.setHeader("Access-Control-Allow-Origin", requestOrigin);
}
When to use: Multiple trusted frontend applications need access to the same API.
Wildcard Origin
Permits requests from any origin. Use this only for public resources where security is not a concern.
Access-Control-Allow-Origin: *
When to use: Public APIs, open data endpoints, or resources intended for unrestricted access.
Warning: Never use wildcards with credentials or sensitive data. Browsers will reject such configurations.
Working with Credentials
To allow requests that include credentials (cookies, authorization headers), you must configure both the origin and credentials headers properly.
Required configuration:
- Explicitly specify the origin (no wildcards)
- Set
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://secure-app.com
Access-Control-Allow-Credentials: true
Example scenario: A logged-in user on https://app.com needs to fetch personalized data from https://api.com using session cookies.
Common Pitfalls and Solutions
| Problem | Risk | Solution |
|---------|------|----------|
| Using wildcard (*) with credentials | Browser blocks the request | Always specify exact origins when credentials are required |
| Accepting any origin dynamically | Security vulnerability | Validate origins against a strict allowlist server-side |
| Missing preflight handling | Complex requests fail | Handle OPTIONS requests for non-simple methods (PUT, DELETE, custom headers) |
| Reflecting origin without validation | Allows any origin to access resources | Never echo the Origin header without validation |
Best Practices
Security recommendations:
- Always validate origins server-side against a strict allowlist
- Never trust client-provided input when setting CORS headers
- Use the most restrictive configuration that meets your requirements
- Regularly audit your CORS configuration for security issues
- Test CORS policies thoroughly across different browsers
Implementation checklist:
- Define clear origin allowlists for each environment (development, staging, production)
- Implement proper preflight request handling for complex requests
- Log and monitor CORS-related errors for security analysis
- Document your CORS policy and the reasoning behind configuration choices
Configuration Quick Reference
| Use Case | Recommended Configuration |
|----------|---------------------------|
| Public API (no authentication) | Access-Control-Allow-Origin: * |
| Single trusted frontend | Access-Control-Allow-Origin: https://app.com |
| Multiple trusted frontends | Dynamic origin validation with allowlist |
| Authenticated requests | Explicit origin + Access-Control-Allow-Credentials: true |
| Development/testing only | Permissive settings (never use in production) |
Learn More
- MDN Web Docs: CORS – Comprehensive documentation with detailed examples and browser compatibility information
- OWASP CORS Cheat Sheet – Security-focused best practices and common vulnerabilities
- W3C CORS Specification – Official technical specification for implementers