Cross-Origin Resource Sharing (CORS)

Cross-Origin Resource Sharing (CORS) is a mechanism that provides secure communication between browsers and servers running on different origins (on different domains or protocols) using additional HTTP headers.

In other words, CORS allows a web application running on www.site1.com to securely access restricted resources on www.site2.com.

Why is CORS important?

For security reasons, browsers restrict HTTP requests from JavaScript code only to the same origin the application was loaded from (the same-origin policy). CORS is a way for the server to check if the request is coming from an allowed origin and tell the browser not to block it.

How CORS works

The CORS standard describes a set of HTTP headers that provide browsers with a way to request different origins only when they have permission to do so. Although the server can perform some validation and authorization, it is the browser’s responsibility to process these CORS headers and to comply with the restrictions that they impose.

For some requests (other than GET and HEAD methods), the browser may request permission from the server by sending a special "preflight" request before sending the actual request. Preflight requests are made by sending an HTTP OPTIONS request with special HTTP headers that contain the origin server address and the actual request method.

Preflight Request with HTTP OPTIONS Method
OPTIONS /api/v1/requests HTTP/1.1
Host: api.reqbin.com
Origin: https://reqbin.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type

The server may send a response and indicate that the origin (https://reqbin.com), request method (POST) and request headers (content-type) are acceptable.

Server Response for Preflight Request
HTTP/1.1 200 OK
Allow: OPTIONS, POST
Access-Control-Allow-Origin: https://reqbin.com
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Headers: content-type

If the server indicates that the request is acceptable, the browser sends the actual request to the server.

Actual POST Request
POST /api/v1/requests HTTP/1.1
Host: api.reqbin.com
Origin: https://reqbin.com
Content-Type: application/json
Content-Length: 459
...

And the server response.

Server Response for POST Request
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://reqbin.com
Content-Type: application/json
Content-Length: 69527
...

Servers may also notify clients whether "credentials" (Cookies and HTTP Authentication data) should be sent with requests.

CORS Request Headers

  • Origin: indicates the origin server name (the script was loaded from).
  • Access-Control-Request-Method: the actual HTTP request method.
  • Access-Control-Request-Headers: the actual HTTP request headers that will be used.

CORS Response Headers

  • Access-Control-Allow-Origin: specifies the origin server that can access the resource or "*".
  • Access-Control-Allow-Credentials: indicates whether the actual request can be made using credentials.
  • Access-Control-Expose-Headers: lists of the headers that browsers are allowed to access.
  • Access-Control-Max-Age: specifies for how long the response of a preflight request can be cached (in seconds).
  • Access-Control-Allow-Methods: list of allowed methods for accessing the resource.
  • Access-Control-Allow-Headers: specifies HTTP headers that can be used for the actual request.

Conclusion

CORS protects thin web fabric. You can use the CORS mechanism by adding the necessary Access-Control- * headers to the server response. Using CORS is the decision of the site owners, and it is controlled by the configuration of the webserver and your server code.

CORS is supported by most modern web browsers. As more app code moves to the client, the need for CORS only grows.