CORS - alexanderteplov/computer-science GitHub Wiki

Cross Origin Resource Sharing

First, start from the same-origin policy.

Same-Origin Policy

The same-origin policy is a security mechanism that generally restricts how a script (javaScript) on some web page (one origin) can interact with a different web page (another origin).

The origin is a combination of a protocol, host and port of a web-page URL. The same-origin means: identical protocol (e.g., https), identical host (e.g. mail.google.com), and identical port (e.g. 80).

The same-origin policy is oriented mostly against embedding legal web pages into criminals' web pages, making fake banking sites, for example. Legal sites may be totally mocked (e.g., via iframe) or some of their functionality may be borrowed with help of hidden elements, like buttons, forms.

The same-origin policy doesn't prevent embedding cross-origin scripts, images, forms, iframes. It only will be forbidden by default for any script on a web page to read any cross-origin resources such as iframe (data from it), image (loading to a canvas or background) and to make requests to cross-origin APIs.

The protection of something like malicious image src attribute is not a same-origin policy business. It's up to Content Security Policy.

CORS as a way to lose same-origin restrictions

To say a browser not to limit scripts on particular or any web pages in communications with cross-origin APIs CORS mechanism was introduced. So, CORS is only a (relatively) safe method to workaround with the same-origin policy.

CORS mostly is represented by the group of headers sent by either server or browser.

Server-side

It's always a server that sets up and controls CORS. Browser only automatically checks CORS settings.

Headers

  • Access-Control-Allow-Origin: <origin> | *
  • Access-Control-Expose-Headers
  • Access-Control-Max-Age
  • Access-Control-Allow-Credentials
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers

Browser side

All cross-origin requests may be divided into two groups.

Simple cross-origin requests

They should satisfy the following conditions.

  1. Allowed methods:
    • GET
    • HEAD
    • POST
  2. Allowed headers:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type with one of following values:
      • application/x-www-form-urlencoded
      • multipart/form-data
      • text/plain
  3. And some limitations for the XMLHttpRequest.

Preflighted cross-origin requests

Any other than simple requests.

Browser preflight such a request with an extra request using the OPTIONS method. From a response to it browser gets to know the CORS settings of the cross-origin server.

An example of preflighted request:

OPTIONS /doc HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

Requests with credentials traits differ

Links

⚠️ **GitHub.com Fallback** ⚠️