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 a term cross domain or cross origin here; so, it’s evident that there must be something like same origin as well. If we understand the same origin concept first, it’ll become easier to understand CORS.
In web application security schemes, same origin policy is an important aspect. In browser, this policy is used to maintain the confidentiality/privacy of information. Using 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 same origin policy helps with security aspect. If so far it’s clear, you can skip the next paragraph; or else read on.
CORS explained with example
Imagine you are 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 browser, a.com’s malicious script can read your bank account information; pretty dangerous! right?
However, having this policy enforced also has some other challenge. 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 same origin policy, it’s impossible to achieve. Here is such scenarios, CORS scheme comes in 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 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 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 protocol, host and port of the requesting page. Example of Origin header may look like following for a requesting page in 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 –