Cross-Origin Resource Sharing (CORS)
How browsers control cross-origin requests and how to configure it safely
Overview
CORS is a browser mechanism that controls which origins (scheme + host + port) may read responses from your API. The same-origin policy blocks cross-origin reads by default, and CORS headers selectively relax that. Misconfiguring CORS can expose private data to any website, so it should be as restrictive as your app allows.
Syntax / Usage
Respond with Access-Control-Allow-Origin for the specific origins you trust. Only enable credentials when you truly need cookies, and never combine credentials with a wildcard.
GET /api/profile HTTP/1.1
Origin: https://app.example.com
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Vary: Origin
Examples
Configure an allowlist rather than reflecting any origin:
const allowed = new Set(["https://app.example.com", "https://admin.example.com"]);
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowed.has(origin)) {
res.setHeader("Access-Control-Allow-Origin", origin);
res.setHeader("Vary", "Origin");
}
next();
});
A public, read-only API with no credentials can safely allow all origins:
Access-Control-Allow-Origin: *
Common Mistakes
- Reflecting the request's
Originheader back without checking an allowlist - Combining
Access-Control-Allow-Origin: *withAllow-Credentials: true - Assuming CORS protects your server — it only restricts browser reads
- Believing CORS replaces CSRF protection (it does not)
- Forgetting the
Vary: Originheader, causing incorrect cached responses
See Also
web-security-fundamentals web-security-csrf web-security-https-tls