CORS or cross origin resource sharing is a W3C specification which allows scripts to make a request to a domain other than the one which it is hosted on.
When a browser based application sends a request to a server in a different domain it is called a “Cross domain” request.
A valid CORS request has a header called domain which is automatically added by the browser.
All browsers traditionally follow the “same origin” policy. This means if a web page say ‘foo.com’ wants to access data in a second web page say ‘bar.com’, both foo.com and bar.com should have the same origin. Origin is defined as a combination of “host name”, “port number” and “URI scheme”. This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page’s Document Object Model.
Let’s take the use case where in foo.com and bar.com have separate origins. The browser itself stops these requests as part of the security measure which prevents scripts from A to access sensitive data from B. However, if the server hosting bar.com has a few special headers added, bar.com can be accessed by foo.com. In that, CORS requires a co-ordination between client and server.
CORS is currently supported in the following browsers:
- Chrome 3+
- Firefox 3.5+
- Opera 12+
- Safari 4+
- Internet Explorer 8+
To query whether CORS is supported or not the following site comes in handy:
Types of CORS requests
Cross-origin requests can be divided into two categories:
- Simple requests
- Complex requests
Simple requests are requests that meet the following criteria:
- HTTP Method matches (case-sensitive) one of:
- HTTP Headers matches (case-insensitive):
- Content-Type, but only if the value is one of:
Simple requests are characterized as such because they can already be made from a browser without using CORS.
Understanding CORS headers
Access-Control-Allow-Origin: Any CORS request always has an "Origin" header. Omitting this header from the request will cause the request to any server fail. A typical http request would look like:
POST /cors HTTP/1.1
The server receiving this request has two options here:
- It can return the response such that the value of header “Access-Control-Allow-Origin” is foo.com. This means Origin “foo.com” is allowed by the server to make a CORS request.
- The response is returned such that the value of header “Access-Control-Allow-Origin” is “*”. “*” is a wild card which allows any server to make a CORS request.
Access-Control-Allow-Credentials(optional): This is an option header sent across by a server in case the request has the ‘withCredentials’ flag set to true. The only valid for this header sent across by the server is “true”. This header indicates whether cookies are allowed in CORS request. If the server does not wish to allow cookies, it omits this header from the response.
Access-Control-Expose-Headers(optional) : This is an optional response header returned by the server. This values of this header is a comma separated list of headers exposed to the client. Any client sending a CORS request can access the following headers of the http response:
If the server wishes to expose additional headers it should return the value of this header.
CORS Preflight Request
A CORS preflight request gets sent across before an actual http request is made. This is sent across automatically by the browser. It is a way of asking permission to make a CORS request. Typically this request gets triggered for content type “application/json”. The OPTIONS http method is used for a CORS preflight.
The response to the preflight request can be cached so that it is not made repeatedly. A CORS preflight consists of the “Origin” header and one of the following:
Access-Control-Request-Method– The HTTP method of the actual request. This request header is always included, even if the HTTP method is a simple HTTP method as defined earlier (GET, POST, HEAD).
Access-Control-Request-Headers– A comma-delimited list of non-simple headers that are included in the request.
In response to the above request headers the server sends across the following in addition to Access-Control-Allow-Origin header::
Access-Control-Allow-Methods (required) – Comma-delimited list of the supported HTTP methods. Although the preflight request asks permissions for a single HTTP method, this response header can include the list of all supported HTTP methods. This is helpful because the preflight response may be cached, so a single preflight response can contain details about multiple request types.
Access-Control-Allow-Headers (required if the request has an
Access-Control-Request-Headers header) – Comma-delimited list of the supported request headers. Like the
Access-Control-Allow-Methods header above, this can list all the headers supported by the server (not only the headers requested in the preflight request).
Access-Control-Max-Age (optional) – Making a preflight request on ‘every’ request becomes expensive, since the browser is making two requests for every client request. The value of this header allows the preflight response to be cached for a specified number of seconds.
CORS support within MII
Support for CORS has been added in MII in 14.0 SP07 and MII 15.0 SP05. The headers explained above need to be added to System properties as below:
Each of these properties correspond to a header stated in section above.
If an MII server Administrator intends to allow CORS he should check Allow Cross Origin Resource Sharing.
Allowed hosts: The hosts which are allowed to make CORS requests. A “*” allows all hosts to make these requests.
Allow credentials: This flag enables MII server to add Access-Control-Allow-Credentials to the response.
Expose Headers: Comma separated list of headers allowed by MII server.
Allow Methods: Comma separated list of http methods allowed for CORS.
Allow Headers: Which headers are allowed in response to preflight request having “Access-Control-Request-Headers“
Maximum Age: Time in seconds for which the preflight response can be cached.
All these properties should be set by MII administrator in order to allow CORS. Administrators should be careful while setting these properties as they might lead to the MII system becoming vulnerable to security threats.