Desarrollo y Mantenimiento de Sistemas Informáticos

4º. 1er cuatrimestre. Itinerario de Sistemas de la Información. Grado en Ingeniería Informática. ULL


GH Org   - GH Template Org   - GitHub Classroom   - Discussions   - Teams   - Campus ULL   - Students Activity   - Chat   - Google Meet

Introduction to CORS

Same origin policy

The default behavior of web browsers that initiate requests from a page via JavaScript is that they follow the same-origin policy.

Two URLs would be considered to be having different origins when they have different protocols, ports (if specified), or hosts.

Origin includes the combination of protocol, domain, and port. This means

are actually different origins and thus impacted by same-origin policy.

In a similar way,

are also different origins. The path or query parameters are ignored when considering the origin.

Under SOP requests can only be made to the same domain. Requests to a different domain will fail.

Websites use cookies to keep track of authentication or session info. Those cookies are bounded to a certain domain when they are created.

On every HTTP call to that domain, the browser will attach the cookies that were created for that domain. This is on every HTTP call, which could be for static images, HTML pages, or even AJAX calls.

This means when you log into https://examplebank.com, a cookie is stored for https://examplebank.com. If that bank is a single-page React app, they may have created a REST API at https://examplebank.com/api for the SPA to communicate via AJAX.

  1. Let’s say you browse to a malicious website https://evilunicorns.com while logged into https://examplebank.com.
  2. Without same-origin policy, that hacker website could make authenticated malicious AJAX calls to https://examplebank.com/api to POST /withdraw even though the hacker website doesn’t have direct access to the bank’s cookies.

This is due to the browser behavior of automatically attaching any cookies bounded to https://examplebank.com for any HTTP calls to that domain, including AJAX calls from https://evilunicorns.com to https://examplebank.com.

By restricting HTTP calls to only ones to the same origin (i.e. the browser tab’s domain), same-origin policy closes some hacker backdoors such as around Cross-Site Request Forgery (CSRF) and Cross-Site Scripting (XSS).

So, all browsers simply restrict script-based network calls to their own domain to make it simple and safe.

Cross-Origin Resource Sharing CORS

CORS allows these cross-domain requests to happen, but only when each side opts into CORS support.

If your server is configured for CORS, it will return an extra header with Access-Control-Allow-Origin on each response.

Sometimes it’s just a helpful website (say, https://my.first.site.foo) trying to use a public API from another origin (say, https://api.github.com). The programmers who worked hard on api.github.com want all origins to access their site’s contents freely. In that case, the API server at api.github.com can use CORS headers to allow my.first.site.foo (or any other requesting origin) to access its API responses.

So, most of the time cross-origin access is a bad thing, but there are cases where it’s a good thing. CORS allows the good case to happen when the requested site wants it to happen.

CORS allows the server to explicitly whitelist certain origin and help to bypass the same-origin policy.

How CORS works

This is how a simple CORS request works:

  1. A browser tab open to https://www.mydomain.com initiates AJAX request GET https://api.mydomain.com/widgets
  2. Along with adding headers like Host, the browser automatically adds the Origin Request Header for cross-origin requests:
  GET /widgets/ HTTP/1.1
  Host: api.mydomain.com
  Origin: https://www.mydomain.com
  [Rest of request...]
  1. The server checks the Origin request header. If the Origin value is allowed, it sets the Access-Control-Allow-Origin to the value in the request header Origin.
     HTTP/1.1 200 OK  
     Access-Control-Allow-Origin: https://www.mydomain.com  
     Content-Type: application/json
     [Rest of response...]  
  1. When the browser receives the response,
    • the browser checks the Access-Control-Allow-Origin header to see if it matches the origin of the tab. If not, the response is blocked.
    • The check passes if either the Access-Control-Allow-Origin matches the single origin exactly or contains the wildcard * operator.
    • A server that responds Access-Control-Allow-Origin: * allows all origins. Use * if your application absolutely requires it, such as creating an open/public API.

If you want to know more about CORS continue reading the section Cross-Origin Resource Sharing CORS: Second Part of the course.

CORS and Fetch API

If you want to avoid the blocking, the server that hosts the resource needs to have CORS enabled. What you can do on the client side is set the mode of fetch to cors (Not really needed, this is the default setting):

fetch(request, {mode: 'cors'});

The mode option specifies the mode you want to use for the request, e.g., cors, no-cors, or same-origin.

However this still requires the server to enable CORS as well, and allow your domain to request the resource.