Cross-Origin Resource Sharing (CORS)
Welcome to Secumantra! In this post we will understand what Cross-Origin Resource Sharing (CORS) is and will try to understand this typical CORS error we face frequently while accessing some URL or when working with APIs.
You might have seen this kind of error many times on your browser console –
In short, Cross-Origin Resource Sharing (CORS) is a standard that allows a server to loosen the restrictions of same-origin policy. So let us begin with what is same-origin policy?
Same-Origin Policy
Many websites use cookies to keep track of user sessions. These cookies are bound to a certain domain and are attached with every HTTP request to that particular domain. For example, when you log into amazon.com, a cookie named x-main is stored for amazon.com and then attached with each subsequent request to amazon.com. It helps server to identify a particular user or session and customize recommendations in this case.
It can be a possible risk and cause of a very common cyber attack, like cross-site request forgery (CSRF). In a CSRF attack an end user’s browser is tricked by an attacker into executing a malicious web request using victim’s authenticated credentials (cookies). The authenticated state of the victim is abused and the browser is tricked into issuing a malicious request.
All modern web browsers have built-in controls to prevent malicious web sites from stealing user’s personal data. So attacks like CSRF are prevented by browsers by implementing a security mechanism called the same-origin policy. The browser will step in and prevent the malicious code from one origin to make an API request to some another origin. It will stop attacker’s site and say “Blocked by the same-origin policy.”
The same-origin policy states that when a user is viewing a web page in a browser, script running on that web page should only be able to read form or write to the content of another web page if both pages have the same origin.
The origin for a site is defined as the combination of protocol (HTTP or HTTPS), its TCP port (usually 80 for HTTP and 443 for HTTPS) and its domain name or host. For example, in https://www.secumantra.com/, the protocol is https://, the host is www.secumantra.com and the port number is 443 (for https, the default port number).
The following table shows the results of attempting a scripting request from http://www.company.com/store/
to specific URLs.
URL | Allow Request? |
https://www.company.com/store/ | No, different protocol (HTTP vs HTTPs) |
http://www.othercompany.com/store/ | No, different domain |
http://my.company.com/store/ | No, different domain |
http://company.com/store/ | No, different domain |
http://www.company.com:8080/store/ | No, different port |
http://www.company.com/other/ | Yes |
Same-origin policy is essentially the foundation of most browser security principles. Without this policy, any site on the internet could access the confidential data from any other site. A world without it would have some amazing web applications, but at the cost of both privacy and security.
Note: Although modern browsers offer some native defenses against CSRF we should not rely on them entirely. The only real mitigation is to use anti-forgery tokens. Always remember defense in depth strategy when dealing with web application security.
Same-origin policy has no effect on what pages or sites any server-side code can access. The server at www.company.com can make requests to my.company.com, google.com or even any intranet sites. The same-origin policy only applies to browsers running client-side scripting code. This is because of cookies.
Cross-Origin Resource Sharing (CORS)
Now we understood same-origin policy and all modern browsers follow it by default. So websites are restricted to access resources from the same origin only. But there might be some legitimate reasons for a website to make cross-origin HTTP requests or your JavaScript app want to make an API call running on a different domain. Cross-Origin Resource Sharing (CORS) is actually a relaxation technique against the same-origin policy implemented in modern browsers.
CORS is a security protocol that enables scripts running on a browser client to interact with resources from a different domain. It uses additional HTTP headers to inform browsers to give a web application running at one origin, access to selected resources from a different origin (a cross-domain request). A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
An example of a cross-origin request: the front-end JavaScript code served from https://first-domain.com uses XMLHttpRequest to make a request for https://second-domain.com/data.json.
For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request resources from the same origin the application was loaded from unless the response from other origins includes the right CORS headers.
Access-Control-Allow-Origin is the HTTP headers that let servers describe which origins are permitted to read the information from a web browser. The Access-Control-Allow-Origin header is included in the response from one server to a request originating from another website, and identifies the permitted origin of the request. A web browser compares the Access-Control-Allow-Origin with the requesting website’s origin and permits access to the response if they match.
The specification of Access-Control-Allow-Origin allows for multiple origins, or the value null, or the wildcard *
. However, as of now no browser supports multiple origins and there are restrictions on the use of the wildcard *
. Here is an example showing either a single origin ; or else the “*
” wildcard, to tell browsers to allow any origin to access the resource.
Access-Control-Allow-Origin: * Access-Control-Allow-Origin: http://example.com:8080
If the CORS configuration is not setup correctly, the browser console shows an error like “Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at “https://some-url-site” indicating that the request was blocked due to violating the CORS security rules.
Request has been blocked by CORS policy: No 'Access-Control-Allow-Origin' headeris present on the requested resource.
This might not necessarily be a set-up mistake, though. It’s possible that the request is in fact intentionally being disallowed by the user’s web application and remote external service. However, If the endpoint is meant to be available, some debugging is needed to find the exact issue.
Browser Support
Although all modern browsers support CORS, we should be aware that CORS is not available in all browsers. Here is a snapshot showing status for different browsers –
Summary
CORS is a relaxation protocol to same-origin policy and act as a security configuration. It provides controlled access for HTTP requests to one website domain from another using a set of HTTP response headers. Browsers permit access to responses to cross-origin requests based upon these header instructions. Note that to fix CORS problems, you need to make changes on the API side adding required response headers.
CORS does not provide protection against cross-site request forgery (CSRF) attacks and it is just a controlled relaxation of the same-origin policy. So proper understanding and configuration of CORS is very important to secure your web applications.
Thank you for reading. Stay Safe, Stay Secure!