logo le blog invivoo blanc

Introduction to CORS (CORS definition)

22 April 2021 | Design & Code, Front-End | 0 comments

Cors definition : our journey starts here:


Figure 1.1: Backend request blocked by the browser

Every front-end developer faced or will face this situation at least once in his/her career. When the webapp becomes more complex, we need to interact with multiple backends and/or make some non-simple REST calls (using custom headers, HTTP verbs other than GET and POST, etc.). But then, the browser refuses to cooperate.

In this article, we will understand why it happens and how the solutions we find on the internet for this problem work and what’s CORS definition.

Here the problem is on the boundary between front and back dev. It consists of a couple of security-related features to implement on the browser and the backend server. As we can see from common questions and answers about this topic on the internet, people on both sides do not take the ti     me to dive into this topic. The solutions usually consist of either disabling it entirely on the backend to allow any requests or running the browser without security checks.

1. Going deeper: origins

In the prehistory of the internet, as soon as browsers started allowing to include scripts in web pages, developers started including third-party scripts on them. As we all know, scripts can be used for many different purposes, from harmless animations to ads, tracking, or social network integration.

This variety creates potential security breaches because these third-party scripts can access user information on the front-end or the backend. For example, a script may try to steal cookies, the local storage, or even use this information to attack sensible applications like banks, email clients, or even local network devices on behalf of the user.

What do you think about random webpages interacting with your home alarm system?

It gets even more dangerous today because most sites embed/call dozens of third-party scripts.

The Same Origin Policy was then born. The browser would let a web page access only resources on pages having the “same-origin”.

Two resources are said to have the same origin if their URL has the same host, port, AND protocol.

For example, https://www.invivoo.com/blog/ and https://www.invivoo.com/contact/ are two pages with the same origin, whereas https://www.invivoo.com/blog/ and https://blog.www.invivoo.com/ are not.

2. Crossing origins (CORS definition)

As soon as the same-origin policy was implemented, it was necessary to provide a solution for the situations where one needs to “cross” origins on a webpage. This solution is called CORS, which stands for Cross-Origin Resource Sharing.

CORS is implemented on top of HTTP so that the backend can tell the browser to authorize front-back interactions. It consists of a preflight request, fired by the browser before each non-simple request. A set of headers should then be included on every server response (preflight or not) to allow a subset of otherwise forbidden interactions.

You may think this approach looks complicated, and it is :). That is why a set of cross origins interactions is allowed by default. That is what is behind the word simple I’ve been using along with this article. The basic rule is that simple requests are allowed by default and do not require CORS. That makes CORS an opt-in protocol. Most websites, therefore, will not need to deal with it until they need it.

As usual in the front-end world, it is challenging to define simple as the exact definition changes from browser to browser. As a rule of thumb, we could say that a simple request uses a HEAD, GET, or POST method. Only a very limited set of headers and content types is allowed. For example, application/JSON is not considered simple. If you want to be helped on this topic, you can contact our Front-End expertise!

3. Let’s code!

To illustrate how the CORS protocol works, I invite you to consider the following example. The complete code source and detailed execution instructions can be found here.

It consists of a front-end HTML page that dispatches Ajax requests to a backend server and a simple NodeJS backend server that implements a minimal version of the CORS protocol.

xhr.open("PUT", "http://"+host+":7771/cors");

We sent PUT requests because we want to be sure our requests are not simple so that the browser will block them by default. Besides, in this code, host is a parameter because we want to see how the browser behaves in different situations.

The idea is to set up two hostnames for the same website (hosta and hostb) and see how the browser reacts when sending a request to each of them from each host.

Below, a simplified version of the server code:

http.createServer((req, res) => {
    let corsHeaders  = {
      "Access-Control-Allow-Origin": "http://hosta:7771",
      "Access-Control-Allow-Methods": "OPTIONS, PUT, GET"
    };

    if (req.url === "/cors") {
      if (req.method === "PUT") {
        res.writeHead(200, corsHeaders);
        res.write("Hello PUT");
        res.end();
      } else if (req.method === "OPTIONS") {
        res.writeHead(204, corsHeaders);
        res.end();
      } else {...}
    }
  })

It declares that methods OPTIONS, PUT, and GET from origin http://hosta:7771 are allowed.

On the following table, you can see the actual requests performed by the browser on each case.

In short:

  • PUT requests will be blocked when running on an unaccepted origin
  • Calls from the same origin do not generate OPTIONS preflight requests

Front end Origin Call hosta   Call hostb  
  Request 1 Request 2 Request 1 Request 2
hosta PUT OPTIONS PUT
hostb OPTIONS Rejected 200

4. Summing up and Further reading

I hope this article could give you a first taste of why CORS exists, of CORS definition, and why it is necessary, and how to configure your backend correctly.

In this section, I leave you a couple of links to go deeper on the topic.

4.1. Authoritative Reference Pages

4.2. Interesting Misc Links

This article was written by Nicolas Erny, expert of our Front-end expertise.