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:

Google Results for searching for CORS documentation

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?


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.


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 request
  • Access-Control-Allow-Origin is the whitelisted origin sent in the Origin 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 beyond GET, HEAD, and POST
  • Access-Control-Expose-Headers allows example.com to read the contents of the X-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.

[Category: Security] [Tags: CORS]