All about CORS (Cross Origin Resource Sharing)

Javed Akhtar
7 min readJan 17, 2020

--

Why One Should Learn CORS ?

You are a back-end-end developer and developing an API and want your API to be accessible by all ORIGIN, you need to understand the concept of CORS.

You are a front-end developer developing a front-end application by using an API developed by some other team to populate your app and you are facing some issues like “cross origin request blocked” or CORS error in your browser console. You should know the problem so that you can understand if the problem is in front-end request or back-end response. As a Developer this much motivation is enough. Let’s dive into CORS.

Understanding Origin within CORS

ORIGIN : An origin is a web request header which is made up of the following three parts: -
protocol, hostname, and port number. This header denotes the address from where the request is being generated.

Protocol : protocol (Set of rules) used for communication e.g. http or https

Hostname : The domain name of the server or the IP. A name which uniquely
identifies every computer hooked up to the Internet via the Domain Name System (DNS).

Port Number : The port number at which the request will be served on the server. If no port is mentioned explicitly then default port will be used e.g. port “80” for http

History behind CORS (Internet world before introduction with CORS mechanism)

To understand why CORS concept is introduced and it is not an error but a security functionality, we need to understand first SAME-ORIGIN-POLICY.

What is SAME-ORIGIN-POLICY ?

Same Origin Policy states that all resources loaded by a browser will be defined by a string which is known as the “origin”. Only resources that have the same origin can reach one another resource’s attributes.

For example:

Assume this base url “http://www.samplecompany.com/” where our site is hosted.
Note- here host = samplecompany.com, protocol = http, port = 80

Let’s look at the following scenarios:

1. If I generate a request to the server with the following url as origin
“http://www.samplecompany.com/employees/employee1.html”, am I allowed to do so?
Answer : Yes, because this url has the same origin protocol (http), hostname
(samplecompany.com) and port(80) are the same, hence it is following SOP.

2. If I generate a request to the server with the following url as origin
“https://www.samplecompany.com/employees/employee1.html”, am I allowed to do so ?
Answer : No, because this url has different protocol, hence it is not following
SOP.

3. If I generate a request to the server with the following url as origin
“http://www.samplecompany.com:81/employees/employee1.html”, am I allowed to do so?
Answer : No, because this url has different port number, hence it is not following
SOP.

4. If I generate a request to the server with the following url as origin
“http://www.samplecompany.com/employees/employee1.html”, am I allowed to do so?
Answer : No, because this url has different host name, hence it is not following
SOP.

Why SAME-ORIGIN-POLICY was Introduced ?


To understand this let us understand the following :
An Iframe is used to display a web page within a web page. Assume that you visited a website “http://www.dp.samplecompany.com” and this website is using an iframe that loads your bank’s website “www.kotak.com” in which you login legally. After logging in, a simple JavaScript call on the http://www.dp.samplecompany.com site could be used to access the DOM elements of www.kotak.com loaded in the iframe, such as your account balance.

Example :

var iframe = document.getElementById(“kotakBankIFrame”);
var balance =
iframe.contentWindow.document.getElementsById(“samplecompany_emp1_bal”).innerHTML;

Similarly a lot can be done.

SOP policy is introduced to prevent such thing and some other many reasons(not only DOM access). This means when the above request will be sent, the origin will be “http://www.dp.samplecompany.com” and not “www.kotak.com”. Since origin is not “www.kotak.com” , the browser won’t allow a request from different origin due to SOP policy.

Why was CORS Introduced ?

Since Same-Origin-Policy (SOP) will not allow request from one origin to another origin, how will the API which I have developed say “www.myApi.com” will be accessible by different origin “www.someOtherOrigin.com” ?

To solve this problem CORS is introduced. By using this policy you can generate a request from one origin to another origin.

Does this mean that it will violate the security for which SOP was introduced?
Answer : No, not at all. In fact, it brings more security with flexibility of requesting from different origins. This flexibility is regulated by following some rules implemented in modern browsers.

Enabling CORS on your server (say: http://localhost:3000 or www.myserver.com) means allowing either all origins in the world to access resources on your server, only a few, or a list of origins allowed to access (e.g. : http://localhost:3001 or www.yourapp.com can only access).

So now if any origin wants to access your bank details and if the origin is not allowed on your bank server, the request will be sent from your browser but the response data won’t be accessible in your origin app from where you sent the request to the server. The browser will throw CORS error in it’s console (see below image).

Note : CORS failures result in errors, but for security reasons, specifics about the error are not available to JavaScript. All the code knows is that an error occurred. The only way to determine what specifically went wrong is to look at the browser’s console for details.

What is CORS ?

CORS is a browser security feature that restricts cross-origin HTTP requests only if the origin from which request is sent is not allowed on the server.

How browser determine whether this origin is allowed or not ?

Determination achieved by reading response headers. The response headers of a request will contain “Access-Control-Allow-origin”. If the server is CORS enabled then the value of this header contains “*”(meaning all origins allowed) or list of origins allowed. If the value of header “Access-Control-Allow-origin” contains the origin from which request has been sent then all well otherwise CORS error will be seen in the browser’s console (as shown in the above pic).

How to enable CORS on server ?

So, it is the responsibility of the developer who built server to add header
“Access-Control-Allow-origin” with every response with proper list of origins or “*”. This will enable the CORS.

Note : If you do not send the header “Access-Control-Allow-origin” with response, No other origin’s app will be allowed to access your API to use the response in their app using javascript, meaning CORS error.

Similarly at more granular level we can set methods as “Access-Control-Allow-Methods” and other headers such as “Access-Control-Allow-Headers”,” Access-Control-Allow-Credentials” to say that these methods and headers are allowed for cross origin requests.

Where Does Preflight Request (OPTIONS method) Appear in picture and why ?

Before CORS came in, the internet world server was built with the assumption that all requests will be always from the same origin. When CORS came into the picture, cross origin requests became possible but the old server was not aware of this.

Now a DELETE request can be executed on the server from different origin. This may cause a lot of damage to all OLD servers which are not aware of CORS. To solve this problem Preflight request is introduced.

How is a preflight request solving the non compatible CORS server problem and advantages in the current world ?

Preflight Requests are defined in modern browser rules as two types of requests — Simple and Non Simple.

1. Simple Request : A request is simple if

A. Request methods are among : GET, HEAD, POST

B. Request Headers are among : Accept, Accept-Language, Content-Type,
Last-Event-ID, DPR, Save-Data, Viewport-Width, Width, Downlink

Only values which are allowed for header “Content-Type” :
application/x-www-form-urlencoded,multipart/form-data,text/plain​

C. No event listeners are registered on any XMLHttpRequestUpload object used in the request; these are accessed using the XMLHttpRequest.uploadproperty.

D. No ReadableStream object is used in the request.
For more : https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

2. Rest are non-simple requests.​

Working of Preflight request :

If the request is non-simple then the browser will send a request with OPTIONS method before sending the actual request. If the OPTIONS method is implemented on the server then the response should contain headers such as “Access-Control-Allow-Methods” and “Access-Control-Allow-Headers” and many more. If the response headers are ok with actual request then only browser will send the actual request to the server otherwise OPTIONS
method will fail and actual request will not be sent.

Solving the non compatible CORS server problem :

Since important and risky requests such as DELETE on a server is a non-simple request, the browser will send preflight request first before actual request. Now OLD server which is unaware of CORS will not have OPTIONS method implemented and hence it will fail. This will create awareness to the server owner and is good for bad requests failure. Hence server owner will
require to update the server.

Advantages of preflight in modern world :
We send a preflight request before accessing actual request to ensure that this request is ok or not for the actual request as per preflight response. This may save a lot of time and processing of server for actual code execution.

For more on preflight request, see: https://stackoverflow.com/questions/15381105/cors-what-
is-the-motivation-behind-introducing-p reflight-requests

--

--

Javed Akhtar

I am a software engineer. I love javascript and it's library(React). I am also a writer, cook, singer, youtuber. website: https://javedinfinite.com