aparnajoshi

Cross-Origin Resource Sharing: A complete tutorial

CORS: What it is and why do we need it?

Cross-Origin resource sharing is a protocol that allows the client from one origin to interact with the resources residing on a different origin. When we say resources, it is things like API calls to fetch some data, images downloads, icons, etc. We need CORS to overwrite the same-origin-policy followed by XMLHttpRequest and fetch. This means that Javascript can only make calls to the URLs that are hosted on the same origin(domain) as that of the script itself. However, there are many scenarios when we would want to use the services belonging provided by a different domain and in such scenarios, cors would come in handy.

Same-origin policy

Browsers implement a security mechanism called same-origin policy. This policy was implemented to fight one of the most common cyber-attacks out there: cross-site request forgery. During cross-site request forgery, a malicious attacker/website tries to hijack the browser's cookie system and attempt to steal resources in the name of an authentic website.

Browser Cookie Policy: Every time an HTTP request is made to a domain from the browser, it attaches any cookie that is stored in the browser related to that domain. This is useful for authentication and for establishing the session. For example: When you log in to https://example.com, the server will set certain session related cookies for https://example.com domain in the browser. Every time you revisit https://example.com or make any API calls to https://example.com the session cookies will be sent along with the request. The API will recognize this cookie and allow access without signing in again and again.

Since the browser automatically attaches all the relevant cookies of a domain during any request, a malicious website would try to send requests to https://example.com from the browser. In such a scenario, the cookies stored in the browser for https://example.com domain will be sent. If the cookies are valid, the malicious website gains access to https://example.com and its resources. This way, a user's account will be subjected to a cross-site request forgery attack.

To prevent this, the browsers have implemented same-origin policy. This means that any requests made from the browser from a given website to the same domain will be allowed. It will stop requests coming from a different domain under same-origin policy.

Why do browsers give CORS error? We know that the Cross-origin requests are usually blocked by the browsers due to security purposes. A webserver not only contains publicly accessible assets such as images and fonts but also contains sensitive information such as personal information of a user. These web servers sometimes provide publicly accessible APIs for other websites to consume and interact with their resources. This could be a form of service being provided by one server to another. Following are the few reasons why cross-origin requests are usually blocked by the browsers:

  • The API being requested doesn't allow cross-origin resource sharing
  • The API exposed allows certain qualified domains to send cross-origin resource sharing
  • The API requires certain headers to be sent to allow cross-origin resource sharing

CORS errors and ways to resolve it

If you have involved in web development for any amount of time, I am sure you must have encountered the following error:

cors

Every time you tried to work with external APIs, you might have faced this error. You might have also tried sending headers such as 'Access-Control-Allow-Headers': '*', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': true along with the request and could find no luck in resolving the CORS error:

angry-kitty

Most of the time, this error can be resolved by adding certain headers like Access-Control-Allow-Origin: "https://example.com". This essentially means that the API server hosted in a different domain trusts our domain and is willing to share its resources. The APIs are built for a common purpose, and APIs cannot start whitelisting every new domain that comes up on the internet. Also, there is no guarantee that the domain which has established the trust today won't turn malicious tomorrow.

So what to do now? Do we give up? What are the ways to resolve this issue?

There are several ways in which cors error can be resolved:

1. Installing Allow-origin plugins in the browser:

If you are only testing an API and want to use its data without dealing with the CORS issue, it is possible to install CORS plugin and make API calls from the browser as if it were requesting the resources from the same domain. Note that the plugin is only a fix in your local machine. The plugin will essentially add Access-Control-Allow-Origin: * header to the response coming from the cross-origin server and tricks the browser into allowing the request to pass through.

2. Use a third-party proxy:

The requests going from our browser can be sent through a proxy server which attaches Access-Control-Allow-Origin: * header to every response it sends back. The cors-anywhere server acts as an intermediary proxy between the client and the server.

In this case, if you want to request to https://example.com, the request would be sent to https://cors-anywhere.herokuapp.com/, along with the information about the original server you want to hit. This solution is a great use-case when we don't want to burden ourselves with any backend programming. We will be making use of cors-anywhere and turning the (browser-server) request into (server-server) request.

3. Build a proxy server.

One of the problems with using a third-party proxy server is the dependency. We cannot confirm its availability and its scalability. We also cannot trust it completely and send client secrets to the proxy server. A better approach is to build a proxy server and host it along with the frontend codebase. This way the requests will be first made to our server residing in the same domain, and then it will be forwarded from our server to https://example.com. This would establish a (server-server) communication and the request will be fulfilled.

CORS errors can be troublesome to front-end developers, especially when we don't have any knowledge regarding backend. In the case of simple applications, we can make use of third party proxy servers and fulfill our requests.


Aparna Joshi

Written by Aparna Joshi who works as a software engineer in Bangalore. Aparna is also a technology enthusiast, writer, and artist. She has an immense passion and curiosity towards psychology and its implications on human behavior. Her links: Blog, Twitter, Email, Newsletter