A page's origin includes scheme, host, and port. When a script requests another origin, the browser applies the cross-origin access rules to decide whether that script may read the response. The server communicates allowed origins through response headers, and some request shapes trigger a preflight check before the actual request. This browser policy does not authenticate the caller: a non-browser client can send a request without obeying it. An endpoint still needs its ordinary session, token, authorization, and input checks. For credentialed browser requests, the server must name an allowed origin rather than use a wildcard, and the client must opt into sending credentials when needed. The example uses a fixed origin allowlist and refuses unknown origins.
Cross-origin requests: read CORS as a browser access policy
Case study
An internal dashboard hosted on one origin reads a case API hosted on another. The API permits only the dashboard origin, so a browser script from an unrelated page cannot read its response. That unrelated page may still attempt a request, and a direct command-line client is unaffected by browser CORS rules; neither fact grants access to private case data. A reviewer session and case-level permission remain necessary. A preflight failure appears in browser developer tools before application code receives the intended response, while a server-side 403 is a separate authorization result.
Working contract
const allowedOrigins = new Set(["https://review.aitrove.test"]);
function accessHeaders(origin) {
if (!allowedOrigins.has(origin)) return {};
return {
"Access-Control-Allow-Origin": origin,
"Access-Control-Allow-Credentials": "true",
Vary: "Origin"
};
}
console.log(Object.keys(accessHeaders("https://review.aitrove.test")).length);
console.log(Object.keys(accessHeaders("https://unknown.aitrove.test")).length);Observed output
3
0Cost and tradeoffs
Checking membership in a small allowlist is expected O(1) with a set. A preflight can add a network round trip, although suitable caching may reduce repeated checks. Reflecting arbitrary Origin values without an allowlist is a policy error, not a performance optimization. If responses vary by Origin, caches must preserve that variation to avoid serving incorrect access headers. The example returns only header decisions; a real server must apply them consistently to both preflight and actual responses without using CORS as a substitute for permission checks.
Common Mistakes
- Do not use Access-Control-Allow-Origin wildcard with credentialed browser access.
- Do not treat CORS as authentication or record authorization.
- Do not reflect any caller-supplied Origin without a policy.
- Do not diagnose every blocked browser read as an API 500.
Continue through the stack
URLs and origins: separate location, query, and fragment; Sessions and CSRF: keep identity on the server; Fetch requests: separate HTTP failure, transport failure, and cancellation.
Failure trace
A frontend on one origin cannot read an API response from another, so a developer sets a wildcard allow-origin value while also expecting cookies to travel. The browser rejects that combination; worse, the team mistakes the CORS header for an authorization decision. Allow only the intended origins with the right credential policy, and still authenticate and authorize each endpoint on the server.
Verification
- Call the API from the intended frontend origin and an unapproved origin; compare browser access.
- Exercise a credentialed request and inspect both preflight and actual response headers.
- Send a direct server-side request without an Origin header and confirm permission checks still apply.
Decision note
CORS controls whether browser script can read a cross-origin response. It is not a firewall for the endpoint: non-browser clients can call the server, so every protected resource needs its own access check.
