What is Cross Origin Resource Sharing Header or CORS header? CORS stands for Cross Origin Resource Sharing. It’s a W3 specification that outlines a mechanism to enable a client to communicate in a cross-domain or cross-origin scenario.
What is CORS?
If you notice, we used the term cross-domain or cross-origin here, so it’s evident that there must be something like the same origin. If we first understand the same origin concept, it’ll become easier to understand CORS.
In web application security schemes, the same-origin policy is an important aspect. In the browser, this policy is used to maintain the confidentiality/privacy of information. Using the same origin policy, web browsers prevent one website’s scripts from accessing resources of another website (different protocol, domain, or port). If this policy is not enforced, a malicious script in one website can fetch sensitive information from another website. Hence, enforcing the same origin policy helps with the security aspect. If so far it’s clear, you can skip the next paragraph; or read on.
CORS explained with an example
Imagine browsing a website (a.com) without knowing it’s malicious. At the same time, you also logged into your bank’s portal (b.com). Now, if the same origin policy isn’t enforced in the browser, a.com’s malicious script can read your bank account information; pretty dangerous! right?
However, having this policy enforced also has some other challenges. This is because it’s very much possible that a website’s script loads images or many other resources from another domain or sub-domain. With the same origin policy, it’s impossible to achieve. Here is such scenarios, the CORS scheme comes into the picture. It provides a restricted and secure way of accessing resources/information from a sub-domain or a different domain altogether.
CORS in Action Scenarios
Cross-origin requests can be broadly divided into the following categories (Reference:- Mozilla article):-
- Simple Requests without CORS preflight (We’ll cover CORS preflight concept in the Complex Requests section below)
- Complex Requests involving CORS preflight
Simple Request without CORS preflight
A cross-origin request is termed simple if the request falls under below criteria –
- HTTP Methods allowed:-
- Request Headers allowed (for a complete list of headers, you can refer to W3 CORS Page): –
- Content-Type allowed:-
In case of a simple request, the browser adds a header called “Origin“. This header contains the requesting page’s protocol, host, and port. An example of Origin header may look like the following for a requesting page on a.com –
This request is then sent to the server (say for example b.com). If the server b.com recognizes this request, it adds a new header “Access-Control-Allow-Origin” in the response. The value of this header can be set by b.com as it deem fit. For example, it may set the exact value present in Origin header or it may as well set a wildcard (*). Wildcard (*) is strictly discouraged unless the resource the public. In case of private or semi-public resource, the server must maintain a white-listed origins and should pass the exact value in the response header. Example of such header may look as below –
If the value passed in this header is not wildcard (*) or if it is not the exact value passed in Origin header, or if the header itself is absent in the response, the browser will throw error and won’t process the response from server.
Important:- A CORS request will always contain “Origin” header. This header is added by browser, a user can not manipulate the value of Origin header. In case of same origin request, some browsers add this header and some do not.
Complex Requests involving CORS preflight
If any request does not fall under the criteria mentioned above, browser treats it as a complex request with a CORS preflight. In such scenario, browser will add few additional headers. In case of CORS with peflight, there are two steps involved –
- STEP 1:- This is the actual Preflight request, where requestor (a page in a.com) uses OPTIONS method to the actual server resource (/resource in b.com). It passes headers requesting the required methods and any custom header (as required). The CORS request header may look like –
123456OPTIONS /resouce HTTP/1.1Origin: http://a.comAccess-Control-Request-Method: DELETEAccess-Control-Request-Headers: Required-Custom-Header............ (any other header as required and set by the requester)............ (any other header as required and set by the requester)
Access-Control-Request-Method holds the method name being requested by requester (a.com) from the server (b.com). Access-Control-Request-Headers holds the methods being requested from the server (b.com) bu the client (a.com)
Server (b.com) will process the above headers. It’ll decide whether or not to honor the request. The server will communicate to the browser with some response headers. The response header may look like –1234Access-Control-Allow-Origin: http://a.comAccess-Control-Allow-Methods: PUT, DELETE, POSTAccess-Control-Allow-Headers: customer-header1, custom-header-2Access-Control-Max-Age: 3600
Once the preflight response reaches the browser, the result will be cached in browser for the time period mentioned in Access-Control-Max-Age header. The value of Access-Control-Max-Age header is in seconds.
The server may optionally remove all the CORS related headers from response, in case it does not want to honor the request made by the browser.
- STEP 2:- If the preflight response is matching the request made by browser (successful permission), the browser then makes the actual request. In case the CORS header is absent or not matches with what was request in the preflight request, the browser won’t make the actual call to the server.
Additional Resources and References
You can refer to following articles for further references and knowledge –