If you're a web developer, CORS is probably a recurring phantom that comes back every other project to steal a whole week. After my most recent wrestle with it, I wanted to write a playbook to the common scenarios, gotchas, and workarounds. I hope it helps you!
Ste PammenterCORS is the bane of my career.16:20 PM - 10 Apr 2019
Cross Origin Resource Sharing (CORS) is a security measure enforced by web browsers which affects calls made from a web browser to a remote resource like an API on another web domain.
The key to understanding CORS is to understand that it is the browser which is blocking, but to allow CORS, the server has to add special headers which satisfy the browser into allowing the connection. As such, CORS blocking doesn't affect back-end solutions that call APIs.
If you are just doing an HTTP GET, HEAD, or POST (with no custom/exotic HTTP headers and a "normal" content-type), then you're making a simple request.
This means there won't be a 'preflight' OPTIONS check.
The simple content-types are:
Here's a big Gotcha - if your API speaks JSON, using
Content-Type: application/json (for example), then that counts as an exotic content type, and you will be subject to a preflight OPTIONS request!
Well, after calling for the endpoint you wanted, like
https://coolapi.example.com/pets/, the browser checks whether the response contains an
Access-Control-Allow-Origin header which lists your site by name or implies it by wildcard (that is,
So, to allow calls to your API from any and all websites, as long as you don't require special headers or anything else mentioned on the MDN description of a simple request, you only have to make sure that your server returns the aforementioned
Access-Control-Allow-Origin: * header.
Complex, or "preflighted" requests are those with extra headers or an unusual content type, and have to be checked first (by the browser) to find out whether the request is safe to send at all.
When the browser thinks a request is complex, it will call ahead to the server with the HTTP
Your server must respond to the OPTIONS verb not only with a matching
Access-Control-Allow-Origin but with other headers that explicitly allow whatever incoming stuff you expect in the request. For example, if you expect a header called
X-Secret-Allergies then your server must respond to the OPTIONS call with a header like:
To allow content types that aren't in the "simple" list above, you have to explicitly add the
Content-Type header to the list in
If your request requires an Authorization header, or an auth cookie of some kind, you can't use a wildcard for your
Allow-Origins list! Yikes! You have to specify domains. I don't know how people are working around this in the wild, except perhaps by rolling their own auth headers or doing some RESTful credentials-in-every-request.
If you're using a framework to abstract HTTP requests, like Axios, Angular
$http, or (cough) JQuery AJAX, then you should look for the
withCredentials option. Setting it to true means that you are sending either an Authorization header or an auth cookie. So you can't have a wildcard allow list, and you must add
Authorization to your
Here is the best explanation of an attack which is stopped by CORS that I have found.
It seems to me that in essence, CORS helps to protect users from evil sites which try to load resources from good sites, hoping that the user is logged into the good site, so that their account information can be pulled across to this evil page and sent off to an evil server.
Check out https://cors-tester.glitch.me/
There may be plenty of tools out there for testing CORS, but I'd like to add mine to the pile.
This is an open source tool hosted on Glitch, which keeps your requests/responses entirely private; they go straight from your browser to whatever API you type in. If that's not good enough, you can even download the two files and run
index.html on your own PC by simply opening it in a browser (no local server required)
I hope this article and the tool help you out.
Tell me about your CORS nightmares in the comments!
Originally published at stegriff.co.uk