CORS (Cross Origin Resource Sharing)

 

Why One Should Learn CORS:

 

You are a backend-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 frontend request or backend 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 Service
(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
request.


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.datagrokr.com/” where our site is hosted.
Note- here host = datagrokr.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.datagrokr.com/employees/employee1.html”, am I allowed to do so?
Answer : Yes, because this url has the same origin protocol (http), hostname
(datagrokr.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.datagrokr.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.datagrokr.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.mydatagrokr.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.datagrokr.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.datagrokr.com site could be used to access the DOM elements of
www.kotak.com loaded in the iframe, such as your account balance.


E.g.
var iframe = document.getElementById("kotakBankIFrame");
var balance =
iframe.contentWindow.document.getElementsById(“datagrokr_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.datagrokr.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 pic).

 

 

 

 

 

 

 

 

 

 

Note : CORS failures result in errors, but for security reasons, specifics about the error
are not available to JavaScript. All the code detects 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

 

References :
1. https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

2.https://stackoverflow.com/questions/15381105/cors-what-is-the-motivation-behind-introducing-
preflight-requests

3. https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html
4. http:www.youtube.com

Written by: Javed Akhtar

  • linkedin

©2017 by DataGrokr