Home Basics of Cross Origin Resource Sharing (CORS)

Basics of Cross Origin Resource Sharing (CORS)

CORS is a browser mechanism which enables controlled access to resources located outside of a given domain. It extends and adds flexibility to SOP. However, it also provides potential for cross domain based attacks, if a website’s CORS policy is poorly configured and implemented. CORS is not a protection against cross origin attacks like CSRF. It uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. This is the Access-Control-Allow-Origin header used in the response. SOP is very restrictive and consequently various approaches have been devised to circumvent the constraints. Many websites interact with subdomains or third party sites in a way that requires full cross origin access. A controlled relaxation of SOP is possible using CORS. CORS Tutorial: A Guide to Cross-Origin Resource Sharing. An example is → Web fonts use CORS. Details of the link in text follow below.

Server generated ACAO header from client specified Origin header

Some applications need to provide access to a number of other domains. Maintaining a list of allowed domains requires ongoing effort, and any mistakes risk breaking functionality. So, they read the Origin header in the request headers and add a response header for ACAO corresponding to the domain read. This could be a malicious resource which can allow access of anti-CSRF tokens, for example, from the vulnerable website.

Errors in parsing Origin header

Some applications that support access from multiple origins do so by using a whitelist of allowed origins. Mistakes often arise when implementing CORS origin whitelists. Some organizations decide to allow access from all their subdomains (including future subdomains not yet in existence) or from various other organizations’ domains including the subdomains. These rules are implemented by matching prefixes, suffixes or using RegEx. So, given an example CORS domain of normal-website.com , the attacker could gain access to the resources by registering a domains such as → hackersnormal-website.com or normal-website.com.evil-user.net.

Whitelisted null origin value

The specification for the Origin header supports the value null. Browsers might send this value in the Origin header in various unusual situations like cross site redirects, requests from serialized data, using the file:// protocol, or to support local development of the application. In this situation, an attacker can use various tricks to generate a cross-domain request containing the value null in the Origin header. This could be done for example in a sandboxed iframe.

Prevention of CORS based attacks

  1. Proper configuration of cross domain requests.
  2. Allow only trusted sites and avoid whitelisting null.
  3. Avoid wildcards in internal networks.

Identifying a CORS Response

The presence of some special headers can be used to determine if a request supports CORS. These also determine if XMLHttpRequest call should continue or fail. A number of headers can be set, but the primary one that can determine which origins can access a resource is the Access-Control-Allow-Origin header. It can allow a wildcard or a specific origin → Access-Control-Allow-Origin: https://example.com.

Understanding CORS Request Types

There are two kinds of CORS requests. The browser determines which kind is used and the decision is abstracted from the user. The kind of request also affects the performance. The types are →

  1. Simple Requests → The browser deems a request to be simple when it meets a certain set of requirements →
    • When the request is one of GETPOST or HEAD
    • CORS safe-listed header is used
    • Only application/x-www-form-urlencodedmultipart/form-data or text/plain values are used in the Content-Type header
    • No event listeners are registered on any XMLHttpRequestUpload object
    • No ReadableStream object is used in the request
  2. Preflight Requests → If a request does not meet the criteria for a simple request, the browser will instead make an automatic preflight request using the OPTIONS method. This is used to determine the exact CORS capabilities of the server which is in turn used to determine if the intended CORS protocol is understood. If the result of the OPTIONS dictates that the request cannot be made, then the actual request to the server will not be executed. The preflight request sets the mode as OPTIONS and sets a couple of headers to describe the actual request that is to follow →
    • Access-Control-Request-Method → The intended method of request (GETPOST)
    • Access-Control-Request-Headers → An indication of the custom headers that will be sent with the request
    • Origin → The usual origin header contains the script’s current origin

    An example of such a request would be →

     curl -i -X OPTIONS localhost:3001/api/ping \
     -H 'Access-Control-Request-Method: GET' \
     -H 'Access-Control-Request-Headers: Content-Type, Accept' \
     -H 'Origin: http://localhost:3000'

    The server will include some Access-Control-* headers within the response to indicate whether the request that follows will be allowed or not. The browser would then decide whether to continue with the request or to abandon it.


PortSwigger: CORS (cross-origin resource sharing)

This post is licensed under CC BY 4.0 by the author.