CORS (Cross-Origin Resource Sharing)
The same-origin policy is an important security concept implemented by web browsers to prevent Javascript code from making requests against a different origin (e.g., different domain) than the one from which it was served. Although the same-origin policy is effective in preventing resources from different origins, it also prevents legitimate interactions between a server and clients of a known and trusted origin.
To improve web applications, developers asked browser vendors to allow cross-domain requests.
UA requests an HTML page from origin O1
. The page references javascript assets hosted on O2
which the browser must retrieve to run. The document runs javascript which makes XMLHttpRequest fetches of resources against O3
.
CORS governs the situations under which the requests to O2
and O3
are permitted to proceed; what information is sent in the requests so that these origins can decide whether to service the request; and ways for O2
and O3
to give hints about their resource sharing policy to UAs.
Simple requests
If a cross-origin request fulfills certain specific criteria it is a ‘simple request’, and is sent more or less normally, with an Origin: O1
header. O3
’s response can use the Origin header to decide whether the request is to be allowed, and either way can expose its CORS policy with respect to the specific resource.
e.g., GET/POST/HEAD without any added headers (or with a body and Content-Type
one of text/plain
, application/x-www-form-urlencoded
, multipart/form-data
) are likely to be simple requests.
Pre-flighting
If a request R1
to O3
is not a simple request, UAs must first send a pre-flight request, R2
, to O3
, that will tell them if R1
should be retrieved.
The preflight request is a request to the same resource with OPTIONS
method. The preflight request must include an Origin
header and may propose what http method it intends to use for R1
and what headers it intends to send for R1
.
If the preflight response is a 2xx, then the origin O3
will have specified its CORS policy for this resource. If the resource is not shared with O1
, then the Access-Control-Allow-Origin
header will be missing or null. If it is shared, then O3
or *
will be the value of that header.
Additional response headers indicate
Access-Control-Allow-Methods
: what HTTP methods may be used in actual requests for the resource,Access-Control-Allow-Headers
: what headers are allowed to be sent in actual requests for the resourceAccess-Control-Max-Age
: how long the UA may cache this policy for this resource,Access-Control-Expose-Headers
: what headers (of responses to actual requests for the resource) may be exposed to clientside codeAccess-Control-Allow-Credentials
: whether the actual request supports user credentials (cookies, HTTP auth, client-side SSL certs)
The actual request
Simple requests, and actual requests that triggered a preflight request, can set any of the headers. For actual requests, some have different meanings than they did in preflight.
Access-Control-Allow-Credentials
- in preflight, this indicates whether the actual request should send credentials
- in the actual request, this indicates whether the response can be exposed to the page