Tuesday, August 06, 2019

What is CORS?

CORS is Cross-Origin Request Security.
You can set up CORS for your site by:
  1. responding appropriately to OPTIONS requests (see the access-control- headers above), and
  2. adding the access-control-allow-origin header to your normal HTTP method responses (GETPOST etc.) as well.

Why is CORS a thing?

In the beginning, javascript was only allowed to make requests to the same server as that bit of javascript came from. This was called the Same-Origin policy. Without the Same Origin Policy, sites would be able to make requests as each other: Mallory's website would be able to call Alice's servers, and the browser would add Alice's authentication cookie to the request.
However, that policy proved restrictive, so CORS was added to allow websites to permit requests from other origins.

How it works

  1. Some javascript tries to send a request to a different domain than where that javascript came from
    // alice.com
    fetch('alice-api.com/add_user', {method: 'post'})
    
  2. The browser does the Same-Origin check and enforces the CORS policy:
    1. The browser sends the "preflight" request. This is an request-method=OPTIONS request to the url (in this case, alice-api.com/add_user):
          Host: alice-api.com
          User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
          Access-Control-Request-Method: POST
          Access-Control-Request-Headers: content-type
          Referer: https://alice.com
          Origin: https://alice.com
          Connection: keep-alive
      
    2. The different domain (in this case, alice-api.com) responds:
          HTTP/2.0 200 OK
          date: Tue, 06 Aug 2019 02:26:03 GMT
          access-control-allow-origin: https://alice.com
          access-control-allow-headers: Authorization,Content-Type,Content-Disposition
          access-control-allow-methods: OPTIONS,HEAD,GET,POST,PUT,PATCH,DELETE
          access-control-allow-credentials: true
          access-control-max-age: 7200
      
  3. Now that CORS has been checked, the browser does the real request to the different domain: request-method=POST to alice-api.com/add_user. The response generated by alice-api.com must ALSO contain the header:
        access-control-allow-origin: https://alice.com
    
    or the browser will not accept it.