Posted 3 months ago. Visible to the public. Repeats.

A quick introduction to CORS

Background

Cross-Site Request Forgery (CSRF) is an attack pattern for websites. A CSRF attack is usually relevant in a browser context, where state is kept for multiple domains (as opposed to independent requests made e.g. with curl). The most common example is authentication via cookies. If a script on https://example.com made requests to https://docs.google.com, the browser would send all cookies for docs.google.com along, effectively given the script access to anything the user has access to. This is a huge security issue.

The Same-Origin Policy (SOP) is a counter-measure for CSRF. It states that scripts in a web page may only access data from the same origin and is implemented by virtually any browser since the 90s. By blocking any cross-site or cross-domain interaction, it mitigates most of the CSRF danger. "Origin" in this context is defined as protocol + hostname + port of the current URL. Example: an AJAX request to https://docs.google.com:443 will not succeed when performed by a script on https://example.com:443.

Note that common CSRF attacks or countermeasures are different from the CSRF description above. This is because SOP mitigates the described straight-forward attack and requires attackers to concoct more complex attacks, which in turn requires CSRF-Tokens and the like.

Cross-Origin Resource Sharing

With SOP, we're safe from unwanted cross-origin interaction ­– but we cannot even intentionally cross the origin border. Sometimes this is necessary, e.g. to access an API that has been moved to its own domain.

Over time, there have been a few approaches to achieve this (document.domain, JSONP, window.postMessage), of which CORS is the youngest. Cross-Origin Resource Sharing is a strategy to manually enable certain origins to interchange data. Because CSRF exploits browser behavior, its mitigation CORS is also implemented by browsers.

CORS procedure

The CORS workflow is basically this: When the browser is told to make a CORS request, it adds an Origin: header with the origin (protocol + hostname + port). The server decides whether access is acceptable for this origin and adds the Access-Control-Allow-Origin: header to the response. If the header contains the origin (or "*" for "any"), the response is processed. If not, it is discarded. This way, CORS puts cross-domain access control in the hands of the requested server.

Certain request types (mostly non-GET requests) require a special "preflight" request that checks server approval upfront. These requests are performed with the HTTP verb OPTIONS. Only when the ACAO header permits access, the normal request is performed. This is a security measure to prevent unauthorized state or data modification.

Allowing multiple origins

The ACAO header can only contain a single value. In order to allow a whitelist of origins, the server must check incoming requests against a list internally, and if allowed, set the ACAO header with the value of request.domain.

Fonts and CORS

In contrast to images/videos/etc, web fonts are subject to SOP and thus require an ACAO header to be used on a different domain.

Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Owner of this card:

Avatar
Dominik Schöler
Last edit:
about 1 month ago
by Dominik Schöler
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Dominik Schöler to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more