CORS exists to solve a narrow, specific problem — letting a browser make a cross-origin request safely, on behalf of the user — and misconfiguring it tends to quietly undo the protection it's supposed to provide.
What CORS actually protects against
By default, browsers prevent JavaScript on one origin from reading responses from a different origin — the Same-Origin Policy. CORS is the mechanism that lets a server explicitly opt certain other origins into being allowed to read its responses via Access-Control-Allow-Origin and related headers. It's a browser-enforced restriction, not a server-side authentication mechanism — non-browser clients (curl, server-to-server calls) aren't affected by CORS at all.
The reflected-origin mistake
A common but dangerous pattern: instead of specifying an explicit allowed origin, the server reflects whatever Origin header the request sent back as the Access-Control-Allow-Origin value. This effectively allows any origin, defeating the purpose entirely — any website can now make cross-origin requests and read the responses as if they were explicitly allowlisted.
# Dangerous: reflects any origin back as allowed
Access-Control-Allow-Origin: <whatever Origin header was sent>
The dangerous combination: wildcard + credentials
Access-Control-Allow-Origin: * combined with Access-Control-Allow-Credentials: true would allow any website to make authenticated cross-origin requests using the victim's cookies and read the response — browsers explicitly block this specific combination for that reason, but a reflected-origin pattern (rather than a literal wildcard) can achieve the same dangerous effect while technically passing browser checks.
Configuring CORS correctly
- Maintain an explicit allowlist of origins that genuinely need cross-origin access.
- Never reflect the
Originheader back unchecked — validate it against the allowlist first. - Only set
Access-Control-Allow-Credentials: truefor origins that specifically need authenticated cross-origin requests, and never alongside a wildcard. - Scope
Access-Control-Allow-MethodsandAccess-Control-Allow-Headersto only what's actually needed, rather than allowing everything.
The bigger picture
CORS misconfiguration doesn't create a vulnerability on its own — it removes a browser-level protection that was covering for the assumption that only your own frontend calls your API. If that assumption was the only thing preventing cross-site abuse, the underlying endpoint likely needed stronger authentication checks regardless of CORS.