Understanding CORS
RTFM… just kidding! There is no manual for the CORS (Cross-Origin Resource Sharing) specification. I really had you going there, didn't I?
Don't worry, it's not your fault. After all, here is what a Google search provides:
Each of these sites contains a wealth of information about CORS, and each of them is far over the head of your average developer. Given the frequent questions that I receive from confused and frightened developers trying to understand these documents, I thought it might be helpful to boil CORS down into a couple simple examples.
Q. If I have static content that depends neither upon cookies nor user-specific URLs and/or parameters and I want to share my site's content with the web, what should I do?
A.
Access-Control-Allow-Origin: *
Q. Well, that is great and all. But what if I want to let a foreign website interact with my site, as a logged-in user, allowing them to do anything they could as if they were on my site? I swear that I understand the risks that this entails and that I really trust this other site to not make any security mistakes such as falling victim to a cross-site scripting (XSS) attack.
A.
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, HEAD, OPTIONS, POST, PUT
Access-Control-Allow-Origin: https://example.com
Access-Control-Expose-Headers: X-Poop-Emoji
Access-Control-Max-Age: 300
Where these headers mean the following:
Access-Control-Allow-Credentials
means that the user's cookies (such as their session cookies) will be sent with the requestAccess-Control-Allow-Origin
is the whitelisted origin sent in theOrigin
header by the browser and not*
nor blindly reflected
And these optional headers mean the following:
Access-Control-Allow-Methods
is the list of allowed HTTP methods beyondGET
,HEAD
, andPOST
Access-Control-Expose-Headers
allows example.com to read the contents of theX-Poop-Emoji
header (💩, obviously)Access-Control-Max-Age
allows example.com to make these requests without preflights for the next 300 seconds
Again, please be aware that you need to be very careful with Access-Control-Allow-Credentials
. Even if you think you're safe by only allowing idempotent methods such as GET
, that might be enough to steal an anti-CSRF token and let attackers go to town with CSRF attacks.
If you need additional documentation about other features in CORS, I highly recommend the frustratingly hard to locate CORS for Developers document by Brad Hill.