Card 08/ 10
CORS Is Not Access Control
CORS stops other websites reading a response in a browser, and stops nothing sent by curl, a script or a server.
CORS is enforced by browsers, on behalf of their users, and by nothing else. A request from curl, a script or another server carries whatever Origin it likes, or none, and receives the full response whatever the CORS headers say. An API that relies on CORS to keep unwanted callers out has no protection at all against anyone outside a browser.
CORS works like a doorman who stops guests arriving through one door only. The comparison breaks further on: a doorman decides who enters, while CORS decides only whether a browser page may read the answer, after the request has already reached the server.
The symptom. A team restricts CORS to its own front end, considers the API private, and later finds it scraped or called directly by scripts that never sent a matching Origin.
From a page on evil.exampleblocked from reading
The browser sends the request, the API answers, and the browser withholds the response from the page because no matching Access-Control-Allow-Origin came back. A simple request was still sent and could still have changed data.
From curlnothing blocked
curl https://api.example.com/users/7 sends no preflight and ignores the CORS headers. If the endpoint answers without checking authentication and authorisation, curl prints the whole response.
Why it happens. CORS errors are what a front-end developer sees when calling another origin, so it feels like the API's gatekeeper. It is the browser's protection for its user, not the API's.
What it costs. Endpoints believed private are open to anyone with an HTTP client.
What to do. Treat CORS as a way to let your own websites in, never as a way to keep others out. Every request must be authenticated and authorised on the server, as if CORS did not exist.
← → move through sections and cards