This document defines a mechanism to enable client-side cross-origin
requests. Specifications that enable an API to make cross-origin requests
to resources can use the algorithms defined by this specification. If
such an API is used on http://example.org
resources, a
resource on http://hello-world.example
can opt in using the
mechanism described by this specification (e.g., specifying
Access-Control-Allow-Origin: http://example.org
as response
header), which would allow that resource to be fetched cross-origin from
http://example.org
.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
Please send comments to public-webappsec@w3.org (archived) by 01 March 2013 with [CORS] at the start of the subject line.
This document was produced jointly by the Web Applications (WebApps) and Web Application Security (WebAppSec) Working Groups, and published by the WebAppSec Working Group.
This document was produced by two groups operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document was published by the Web Applications (WebApps) and Web Application Security (WebAppSec) Working Group as a Candidate Recommendation. There is no preliminary implementation report. The Working Groups have not identified any feature at risk. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-webappsec@w3.org (subscribe, archives). W3C publishes a Candidate Recommendation to indicate that the document is believed to be stable and to encourage implementation by the developer community. This Candidate Recommendation is expected to advance to Proposed Recommendation no earlier than 01 March 2013. All feedback is welcome. A diff-marked version against the previous version of this document is available.
Publication as a Candidate Recommendation does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
The entrance criteria for this document to enter the Proposed Recommendation stage is to have a minimum of two independent and interoperable user agents that implement each feature of this specification, which will be determined by passing the user agent tests defined in the test suite developed by the Working Group.
Access-Control-Allow-Origin
Response HeaderAccess-Control-Allow-Credentials
Response HeaderAccess-Control-Expose-Headers
Response HeaderAccess-Control-Max-Age
Response HeaderAccess-Control-Allow-Methods
Response HeaderAccess-Control-Allow-Headers
Response HeaderOrigin
Request HeaderAccess-Control-Request-Method
Request HeaderAccess-Control-Request-Headers
Request HeaderThis section is non-normative.
User agents commonly apply same-origin restrictions to network requests. These restrictions prevent a client-side Web application running from one origin from obtaining data retrieved from another origin, and also limit unsafe HTTP requests that can be automatically launched toward destinations that differ from the running application's origin.
In user agents that follow this pattern, network requests typically include user credentials with cross-origin requests, including HTTP authentication and cookie information.
This specification extends this model in several ways:
A response can include an
Access-Control-Allow-Origin
header, with the origin of where the request originated from as the
value, to allow access to the resource's contents.
The user agent validates that the value and origin of where the request originated match.
User agents can discover via a preflight request whether a cross-origin resource is prepared to accept requests, using a non-simple method, from a given origin.
This is again validated by the user agent.
Server-side applications are enabled to discover that an HTTP request
was deemed a cross-origin request by the user agent, through the
Origin
header.
This extension enables server-side applications to enforce limitations (e.g. returning nothing) on the cross-origin requests that they are willing to service.
This specification is a building block for other specifications, so-called CORS API specifications, which define how this specification is used. Examples are Server-Sent Events and XMLHttpRequest. [EVENTSOURCE] [XHR]
The CORS wiki page provides more background information about this document.
If a resource author has a simple text resource residing at
http://example.com/hello
which contains the string
"Hello World!" and would like http://hello-world.example
to
be able to access it, the response combined with a header
introduced by this specification could look as follows:
Access-Control-Allow-Origin: http://hello-world.example
Hello World!
Using XMLHttpRequest
a client-side
Web application on http://hello-world.example
can access
this resource as follows:
var client = new XMLHttpRequest()
client.open("GET", "http://example.com/hello")
client.onreadystatechange = function() { /* do something */ }
client.send()
It gets slightly more complicated if the resource author wants to be
able to handle cross-origin requests using methods other than
simple methods. In that case
the author needs to reply to a preflight request that uses the
OPTIONS
method and then needs to handle the actual request
that uses the desired method (DELETE
in this example) and
give an appropriate response. The response to the preflight request could
have the following headers specified:
Access-Control-Allow-Origin: http://hello-world.example
Access-Control-Max-Age: 3628800
Access-Control-Allow-Methods: PUT, DELETE
The
Access-Control-Max-Age
header indicates how long the response can be cached, so that for
subsequent requests, within the specified time, no preflight request has
to be made. The
Access-Control-Allow-Methods
header indicates the methods that can be used in the actual request. The
response to the actual request can simply contain this header:
Access-Control-Allow-Origin: http://hello-world.example
The complexity of invoking the additional preflight request is
the task of the user agent. Using
XMLHttpRequest
again and assuming the
application were hosted at http://calendar.example/app
the
author could use the following ECMAScript snippet:
function deleteItem(itemId, updateUI) {
var client = new XMLHttpRequest()
client.open("DELETE", "http://calendar.example/app")
client.onload = updateUI
client.onerror = updateUI
client.onabort = updateUI
client.send("id=" + itemId)
}
This specification is written for resource authors and user agents. It includes advice for specifications that define APIs that use the cross-origin request algorithm defined in this specification — CORS API specifications — and the general security considerations section includes some advice for client-side Web application authors.
As well as sections and appendices marked as non-normative, all diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
In this specification, The words must and may are to be interpreted as described in RFC 2119. [RFC2119]
Requirements phrased in the imperative as part of algorithms (e.g. "terminate the algorithm") are to be interpreted with the meaning of the key word (e.g. must) used in introducing the algorithm.
A conformant resource is one that implements all the requirements listed in this specification that are applicable to resources.
A conformant user agent is one that implements all the requirements listed in this specification that are applicable to user agents.
User agents and resource authors may employ any algorithm to implement this specification, so long as the end result is indistinguishable from the result that would be obtained by the specification's algorithms.
Some terminology in this specification is from The Web Origin Concept HTML, HTTP and URI. [ORIGIN] [HTML] [HTTP] [URI]
Terminology is generally defined throughout the specification. However, the few definitions that did not really fit anywhere else are defined here instead.
Comparing two strings in a case-sensitive manner means comparing them exactly, codepoint for codepoint.
Comparing two strings in an ASCII case-insensitive manner means comparing them exactly, codepoint for codepoint, except that the characters in the range U+0041 LATIN CAPITAL LETTER A to U+005A LATIN CAPITAL LETTER Z and the corresponding characters in the range U+0061 LATIN SMALL LETTER A to U+007A LATIN SMALL LETTER Z are considered to also match.
Converting a string to ASCII lowercase means replacing all characters in the range U+0041 LATIN CAPITAL LETTER A to U+005A LATIN CAPITAL LETTER Z with the corresponding characters in the range U+0061 LATIN SMALL LETTER A to U+007A LATIN SMALL LETTER Z).
The term user credentials for the purposes of this
specification means cookies, HTTP authentication, and client-side SSL
certificates. Specifically it does not refer to proxy authentication or
the Origin
header.
[COOKIES]
The term cross-origin is used to mean non same origin.
A method is said to be a simple method if it is a case-sensitive match for one of the following:
GET
HEAD
POST
A header is said to be a
simple header if the header field name is an
ASCII case-insensitive match for Accept
,
Accept-Language
, or Content-Language
or if it
is an ASCII case-insensitive match for
Content-Type
and the header field value media type (excluding
parameters) is an ASCII case-insensitive match for
application/x-www-form-urlencoded
,
multipart/form-data
, or text/plain
.
A header is said to be a simple response header if the header field name is an ASCII case-insensitive match for one of the following:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
When parsing a header the header must be parsed per the corresponding ABNF production in the syntax section. If the header does not match the production it is said that header parsing failed.
This section is non-normative.
Security requirements and considerations are listed throughout this specification. This section lists advice that did not fit anywhere else.
A simple cross-origin request has been defined as congruent
with those which may be generated by currently deployed user agents that do
not conform to this specification. Simple cross-origin requests generated
outside this specification (such as cross-origin form submissions using
GET
or POST
or cross-origin GET
requests resulting from script
elements) typically include
user credentials, so resources conforming to this specification
must always be prepared to expect simple cross-origin requests with
credentials.
Because of this, resources for which simple requests have significance other than retrieval must protect themselves from Cross-Site Request Forgery (CSRF) by requiring the inclusion of an unguessable token in the explicitly provided content of the request. [CSRF]
This specification defines how to authorize an instance of an application from a foreign origin, executing in the user agent, to access the representation of the resource in an HTTP response. Certain types of resources should not attempt to specify particular authorized origins, but instead either deny or allow all origins.
A resource that is not useful to applications from other origins, such as a login page, ought not to return an
Access-Control-Allow-Origin
header. The resource still must protect itself against CSRF attacks, such
as by requiring the inclusion of an unguessable token in the explicitly
provided content of the request. The security properties of such resources
are unaffected by user-agents conformant to this specification.
A resource that is publicly accessible, with no access control checks,
can always safely return an
Access-Control-Allow-Origin
header whose value is "*
".
A GET
response whose entity body happens to parse as
ECMAScript can return an
Access-Control-Allow-Origin
header whose value is "*
" provided there are no sensitive
comments as it can be accessed cross-origin using an HTML
script
element. If needed, such resources can implement access
control and CSRF protections as described above.
Requests made with user credentials,
or the Origin
header
require special consideration.
When requests have significance other than retrieval, and when relying on the Origin
header, resources must be careful to distinguish between authorizing a request (including its side-effects) and authorizing access to the representation of that resource in the response.
Authorization for a request should be performed using only the intersection of the authority of the user and the requesting origin(s).
It is often appropriate for resources to require an authorization ceremony which explicitly asks for a user to consent that cross-origin requests with credentials be honored from a given origin. In such cases, passing security tokens explicitly as part of the cross-origin request can remove any ambiguity as to the scope of authorization. OAuth is an example of this pattern. [OAUTH]
Use of user credentials in a cross-origin request is appropriate when:
A cross-origin request with credentials as defined in this specification is used to substitute for alternate methods of authenticated resource sharing, such as server-to-server back channels, JSONP, or cross-document messaging. [JSONP] [HTML]
This substitution can expose additional attack surface in some cases, as a cross-site scripting vulnerability in the requesting origin can allow elevation of privileges against the requested resource when compared to a server-to-server back channel.
As a substitute for JSONP-style cross-origin credentialed requests, use of this specification significantly improves the security posture of the requesting application, as it provides cross-origin data access whereas JSONP operates via cross-origin code-injection.
As a substitute for cross-origin communication techniques relying on loading a resource, with credentials, into an HTML iframe
element, and subsequently employing cross-document messaging or other cross-origin side channels, this specification provides a roughly equivalent security posture. Again, data received from origins that are not completely trusted has to be validated to conform to expected formats and authorized values.
For requests to resources that have no significance other than retrieval, and where the credentials are used only to provide user-specific customization for otherwise publicly accessible information. In this case, restricting access to certain origins may protect user privacy by preventing customizations from being used to identify a user, except at authorized origins.
When this specification is used for requests which have significance other than retrieval and which involve coordination between or data originating from more than two origins, (e.g. between resources enabling editing, printing and storage, each at distinct origins) requests ought to set the omit credentials flag and resources ought to perform authorization using security tokens explicitly provided in the content of the request, especially if the origins are not all mutually and completely trusted.
In such multi-origin scenarios, a malicious resource at one of the origins may be able to enlist the user-agent as a confused deputy and elevate its privileges by abusing user credentials sent with cross-origin requests. Avoiding such attacks requires that the coordinating applications have explicit knowledge of the scope of privilege for each origin and that all parameters and instructions received are carefully validated at each step in the coordination to ensure that effects implied do not exceed the authority of the originating principal. [CONFUSED]
Given the difficulty of avoiding such vulnerabilities in multi-origin interactions it is recommended that, instead of using user credentials automatically attached to the request by the user agent, security tokens which specify the particular capabilities and resources authorized be passed as part of the explicit content of a request. OAuth again provides an example of such a pattern.
Authors of client-side Web applications are strongly encouraged to validate content retrieved from a cross-origin resource as it might be harmful.
Web applications that are not uniquely identified by specific host names, and/or mapped to specific ports, do not necessarily have a unique origin, and thus will not be able to securely utilize the mechanism defined in this specification. This is because an origin is composed of only the scheme, hostname, and port.
For example, a web application whose URL is of the type
example.org/app-name/
and the app-name portion is necessary to distinguish the
web application from other web applications also running at example.org, will
be unable to securely employ the mechanism defined in this specification.
Mapping web applications to distinct origins is vital for secure web applications.
This section defines the syntax of the new headers this specification introduces. It also provides a short description of the function of each header.
The resource processing model section details how resources are to use these headers in a response. Likewise, the user agent processing model section details how user agents are to use these headers.
The ABNF syntax used in this section is from HTTP/1.1. [HTTP]
HTTP/1.1 is used as ABNF basis to ensure that the new headers have equivalent parsing rules to those introduced in that specification.
HTTP/1.1 currently does not make leading OWS implied in header value definitions but that form is assumed here.
Access-Control-Allow-Origin
Response HeaderThe
Access-Control-Allow-Origin
header indicates whether a resource can be shared based by returning the
value of the Origin
request header, "*", or "null" in the
response. ABNF:
Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" origin-list-or-null | "*"
In practice the
origin-list-or-null
production is
more constrained. Rather than allowing a space-separated list of
origins, it is either a
single origin or the string
"null
".
Access-Control-Allow-Credentials
Response HeaderThe
Access-Control-Allow-Credentials
header indicates whether the response to request can be
exposed when the omit credentials flag is unset. When part
of the response to a preflight request it indicates that the
actual request can include user credentials.
ABNF:
Access-Control-Allow-Credentials: "Access-Control-Allow-Credentials" ":" true true: %x74.72.75.65 ; "true", case-sensitive
Access-Control-Expose-Headers
Response HeaderThe
Access-Control-Expose-Headers
header indicates which headers are safe to expose to the API of a
CORS API specification. ABNF:
Access-Control-Expose-Headers = "Access-Control-Expose-Headers" ":" #field-name
Access-Control-Max-Age
Response HeaderThe
Access-Control-Max-Age
header indicates how long the results of a preflight request
can be cached in a preflight result cache. ABNF:
Access-Control-Max-Age = "Access-Control-Max-Age" ":" delta-seconds
Access-Control-Allow-Methods
Response HeaderThe
Access-Control-Allow-Methods
header indicates, as part of the response to a
preflight request, which methods can be used during the
actual request. ABNF:
Access-Control-Allow-Methods: "Access-Control-Allow-Methods" ":" #Method
Access-Control-Allow-Headers
Response HeaderThe
Access-Control-Allow-Headers
header indicates, as part of the response to a
preflight request, which header field names can be used
during the actual request. ABNF:
Access-Control-Allow-Headers: "Access-Control-Allow-Headers" ":" #field-name
Origin
Request HeaderThe
Origin
header indicates where the cross-origin request or
preflight request originates from.
[ORIGIN]
Access-Control-Request-Method
Request HeaderThe
Access-Control-Request-Method
header indicates which method will be used in the
actual request as part of the
preflight request. ABNF:
Access-Control-Request-Method: "Access-Control-Request-Method" ":" Method
Access-Control-Request-Headers
Request HeaderThe
Access-Control-Request-Headers
header indicates which headers will be used in the
actual request as part of the
preflight request. ABNF:
Access-Control-Request-Headers: "Access-Control-Request-Headers" ":" #field-name
This section describes the processing models that resources have to implement. Each type of request a resource might have to deal with is described in its own subsection.
The resource sharing policy described by this specification is bound to a particular resource. For the purposes of this section each resource is bound to the following:
A list of origins consisting of zero or more origins that are allowed access to the resource.
This can include the origin of the resource itself though be aware that requests to cross-origin resources can be redirected back to the resource.
A list of methods consisting of zero or more methods that are supported by the resource.
A list of headers consisting of zero or more header field names that are supported by the resource.
A list of exposed headers consisting of zero or more header field names of headers other than the simple response headers that the resource might use and can be exposed.
A supports credentials flag that indicates whether the resource supports user credentials in the request. It is true when the resource does and false otherwise.
In response to a simple cross-origin request or actual request the resource indicates whether or not to share the response.
If the resource has been relocated, it indicates whether to share its new URL.
Resources must use the following set of steps to determine which additional headers to use in the response:
If the Origin
header is not
present terminate this set of steps. The request is outside the scope of
this specification.
If the value of the Origin
header is not a case-sensitive match for any of the values
in list of origins, do not set any additional headers and
terminate this set of steps.
Always matching is acceptable since the list of origins can be unbounded.
If the resource supports credentials add a single
Access-Control-Allow-Origin
header, with the value of the Origin
header as value, and add a single
Access-Control-Allow-Credentials
header with the case-sensitive string
"true
" as value.
Otherwise, add a single
Access-Control-Allow-Origin
header, with either the value of the
Origin
header or the string
"*
" as value.
The string "*
" cannot be used for a
resource that supports credentials.
If the list of exposed headers is not empty add one
or more
Access-Control-Expose-Headers
headers, with as values the header field names given in the
list of exposed headers.
By not adding the appropriate headers resource can also
clear the preflight result cache of all entries where
origin is a case-sensitive
match for the value of the Origin
header and url is a
case-sensitive match for the
URL of the
resource.
In response to a preflight request the resource indicates which methods and headers (other than simple methods and simple headers) it is willing to handle and whether it supports credentials.
Resources must use the following set of steps to determine which additional headers to use in the response:
If the Origin
header is not
present terminate this set of steps. The request is outside the scope of
this specification.
If the value of the Origin
header is not a case-sensitive match for any of the
values in list of origins do not set any additional headers
and terminate this set of steps.
Always matching is acceptable since the list of origins can be unbounded.
The Origin
header can
only contain a single origin as the
user agent will not follow redirects.
Let method be the value as result of
parsing the
Access-Control-Request-Method
header.
If there is no
Access-Control-Request-Method
header or if parsing failed,
do not set any additional headers and terminate this set of steps. The
request is outside the scope of this specification.
Let header field-names be the values as result of
parsing the
Access-Control-Request-Headers
headers.
If there are no
Access-Control-Request-Headers
headers let header field-names be the empty list.
If parsing failed do not set any additional headers and terminate this set of steps. The request is outside the scope of this specification.
If method is not a case-sensitive match for any of the values in list of methods do not set any additional headers and terminate this set of steps.
Always matching is acceptable since the list of methods can be unbounded.
If any of the header field-names is not a ASCII case-insensitive match for any of the values in list of headers do not set any additional headers and terminate this set of steps.
Always matching is acceptable since the list of headers can be unbounded.
If the resource supports credentials add a single
Access-Control-Allow-Origin
header, with the value of the Origin
header as value, and add a single
Access-Control-Allow-Credentials
header with the case-sensitive string
"true
" as value.
Otherwise, add a single
Access-Control-Allow-Origin
header, with either the value of the
Origin
header or the string
"*
" as value.
The string "*
" cannot be used for a
resource that supports credentials.
Optionally add a single
Access-Control-Max-Age
header with as value the amount of seconds the user agent is allowed to
cache the result of the request.
If method is a simple method this step may be skipped.
Add one or more
Access-Control-Allow-Methods
headers consisting of (a subset of) the
list of methods.
If a method is a simple method it does not need to be listed, but this is not prohibited.
Since the list of methods can be unbounded simply returning method can be enough.
If each of the header field-names is a
simple header and none is Content-Type
, than
this step may be skipped.
Add one or more
Access-Control-Allow-Headers
headers consisting of (a subset of) the
list of headers.
If a header field name is a simple header and
is not Content-Type
, it is not required to be listed.
Content-Type
is to be listed as only a subset of its values
makes it qualify as simple header.
Since the list of headers can be unbounded simply returning headers can be enough.
This section is non-normative.
Resource authors are strongly encouraged to ensure that requests using
safe methods, e.g. GET
or OPTIONS
, have no side
effects so potential attackers cannot modify the user's data easily. If
resources are set up like this attackers would effectively have to be on
the list of origins to do harm.
In addition to checking the Origin
header, resource authors are strongly encouraged to also check the
Host
header. That is, make sure that the host name provided
by that header matches the host name of the server on which the resource
resides. This will provide protection against DNS rebinding attacks.
To provide integrity protection of resource sharing policy statements usage of SSL/TLS is encouraged.
This section is non-normative.
Resources that wish to enable themselves to be shared with multiple
Origins
but do not respond uniformly with "*"
must in practice generate the Access-Control-Allow-Origin
header dynamically in response to every request they wish
to allow. As a consequence, authors of such resources should send a
Vary: Origin
HTTP header or provide other appropriate control
directives to prevent caching of such responses, which may be inaccurate
if re-used across-origins.
This section describes the processing models that user agents have to implement.
The processing models in this sections need to be referenced by a CORS API specification that defines when the algorithm is invoked and how the return values are to be handled. The processing models are not suitable for standalone use.
The cross-origin request algorithm takes the following parameters:
The request URL is modified in face of redirects.
The method for the request. GET
, unless explicitly
set.
A list of headers set by authors for the request. Empty, unless explicitly set.
The entity body for the request. Missing, unless explicitly set.
The origin of the request.
Due to the specifics of some APIs this cannot be defined in a generic way and therefore it has to be provided as argument.
Either a Document
or
URL. Used to determine the
Referer
header.
Set when redirects are not to be automatically followed.
Set when user credentials are to be excluded in the request and when cookies are to be ignored in its response.
Set when a preflight request is required.
The cross-origin request algorithm can be used by CORS API specifications who wish to allow cross-origin requests for the network APIs they define.
CORS API specifications are free to limit the abilities of a cross-origin request. E.g., the omit credentials flag could always be set.
When the cross-origin request algorithm is invoked, these steps must be followed:
If for some reason the user agent does not want to make the request terminate this algorithm and set the cross-origin request status to network error.
The request URL could have been blacklisted by the user in some fashion.
If the following conditions are true, follow the simple cross-origin request algorithm:
The request method is a simple method and the force preflight flag is unset.
Each of the author request headers is a simple header or author request headers is empty.
Otherwise, follow the cross-origin request with preflight algorithm.
Cross-origin requests using a method that is simple with author request headers that are not simple will have a preflight request to ensure that the resource can handle those headers. (Similarly to requests using a method that is not a simple method.)
User agents must filter out all response headers
other than those that are a simple response header or of
which the field name is an ASCII case-insensitive match for
one of the values of the
Access-Control-Expose-Headers
headers (if any), before exposing response headers to APIs defined in
CORS API specifications.
The
getResponseHeader()
method of XMLHttpRequest
will therefore
not expose any header not indicated above.
Each cross-origin request has an associated cross-origin request status that CORS API specifications that enable an API to make cross-origin requests can hook into. It can take at most two distinct values over the course of a cross-origin request. The values are:
The source origin is the initial
origin that user agents must use for
the Origin
header. It can be modified
during the redirect steps.
The steps below describe what user agents must do for a simple cross-origin request:
Apply the make a request steps and observe the request rules below while making the request.
Apply the redirect steps.
Apply the abort steps.
In case of DNS errors, TLS negotiation failure, or other type of network errors, apply the network error steps. Do not request any kind of end user interaction.
This does not include HTTP responses that indicate some type of error, such as HTTP status code 410.
Perform a resource sharing check. If it returns fail, apply the network error steps. Otherwise, if it returns pass, terminate this algorithm and set the cross-origin request status to success. Do not actually terminate the request.
To protect resources against cross-origin requests that could not originate from certain user agents before this specification existed a preflight request is made to ensure that the resource is aware of this specification. The result of this request is stored in a preflight result cache.
The steps below describe what user agents must do for a cross-origin request with preflight. This is a request to a non same-origin URL that first needs to be authorized using either a preflight result cache entry or a preflight request.
Go to the next step if the following conditions are true:
For request method there either is a method cache match or it is a simple method and the force preflight flag is unset.
For every header of author request headers there either is a header cache match for the field name or it is a simple header.
Otherwise, make a
preflight request.
Fetch the request URL
from origin source origin using
referrer source as override referrer source
with the manual redirect flag and the
block cookies flag set, using the method
OPTIONS
, and with the following additional constraints:
Include an
Access-Control-Request-Method
header with as header field value the request method (even
when that is a simple method).
If author request headers is not empty include an
Access-Control-Request-Headers
header with as header field value a comma-separated list of the header
field names from author request headers in lexicographical
order, each converted to ASCII lowercase (even when one or
more are a simple header).
Exclude the author request headers.
Exclude user credentials.
Exclude the request entity body.
The following request rules are to be observed while making the preflight request:
Apply the abort steps.
Apply the network error steps.
The cache and network error steps are not used here as this is about an actual network error.
In case of DNS errors, TLS negotiation failure, or other type of network errors, apply the network error steps. Do not request any kind of end user interaction.
This does not include HTTP responses that indicate some type of error, such as HTTP status code 410.
The cache and network error steps are not used here as this is about an actual network error.
If the resource sharing check returns fail, apply the cache and network error steps.
Let methods be the empty list.
If there are one or more
Access-Control-Allow-Methods
headers let methods be the values as result of
parsing the headers.
If parsing failed apply the cache and network error steps.
If methods is still the empty list and the force preflight flag is set, append the request method to methods.
This ensures that preflight requests that happened solely because of the force preflight flag are cached too.
Let headers be the empty list.
If there are one or more
Access-Control-Allow-Headers
headers let headers be the values as result of
parsing the headers.
If parsing failed apply the cache and network error steps.
If request method is not a case-sensitive match for any method in methods and is not a simple method, apply the cache and network error steps.
If the field name of each header in author request headers is not an ASCII case-insensitive match for one of the header field names in headers and the header is not a simple header, apply the cache and network error steps.
If for some reason the user agent is unable to provide a preflight result cache (e.g. because of limited disk space) go to the next step in the overall set of steps (i.e. the actual request).
If there is a single
Access-Control-Max-Age
header, parse it and let
max-age be the resulting value.
If there is no such header, there is more than one such header, or parsing failed, let max-age be a value at the discretion of the user agent (zero is allowed).
If the user agent imposes a limit on the max-age field value and max-age is greater than that limit let max-age be the limit.
For each method in methods for which there is a method cache match set the max-age field value of the matching entry to max-age.
For each method in methods for which there is no method cache match create a new entry in the preflight result cache with the various fields set as follows:
For each header in headers for which there is a header cache match set the max-age field value of the matching entry to max-age.
For each header in headers for which there is no header cache match create a new entry in the preflight result cache with the various fields set as follows:
Set the cross-origin request status to preflight complete.
This is the actual request. Apply the make a request steps and observe the request rules below while making the request.
Apply the cache and network error steps.
Apply the abort steps.
In case of DNS errors, TLS negotiation failure, or other type of network errors, apply the network error steps. Do not request any kind of end user interaction.
This does not include HTTP responses that indicate some type of error, such as HTTP status code 410.
Perform a resource sharing check. If it returns fail, apply the cache and network error steps. Otherwise, if it returns pass, terminate this algorithm and set the cross-origin request status to success. Do not actually terminate the request.
Consider the following scenario:
The user agent gets the request from an API, such as
XMLHttpRequest
, to perform a
cross-origin request using the custom XMODIFY
method from
source origin http://example.org
to
http://blog.example/entries/hello-world
.
The user agent performs a preflight request using
the OPTIONS
method to
http://blog.example/entries/hello-world
and includes the
Origin
and
Access-Control-Request-Method
headers with the appropriate values.
The response to that request includes the following headers:
Access-Control-Allow-Origin: http://example.org Access-Control-Max-Age: 2520 Access-Control-Allow-Methods: PUT, DELETE, XMODIFY
The user agent then performs the desired request using the
XMODIFY
method to
http://blog.example/entries/hello-world
as this was allowed
by the resource. In addition, for the coming forty-two minutes, no
preflight request will be needed.
As mentioned, a cross-origin request with preflight uses a preflight result cache. This cache consists of a set of entries. Each entry consists of the following fields:
Access-Control-Max-Age
header value.Access-Control-Allow-Methods
headers.Access-Control-Allow-Headers
headers.To be clear, the method and header fields are mutually exclusive. When one of them is empty the other is non-empty.
The primary key of an entry consists of all fields excluding the max-age field.
Entries must be removed when the time specified in the max-age field has passed since storing the entry. Entries can also be added and removed per the algorithms below. They are added and removed in such a way that there can never be duplicate items in the cache.
User agents may clear cache entries before the time specified in the max-age field has passed.
Although this effectively makes the preflight result cache optional, user agents are strongly encouraged to support it.
The variables used in the generic set of steps are part of the algorithms that invoke these set of steps.
Whenever the make a request steps are applied, fetch the request URL from origin source origin using referrer source as override referrer source with the manual redirect flag set, and the block cookies flag set if the omit credentials flag is set. Use method request method, entity body request entity body, including the author request headers, and include user credentials if the omit credentials flag is unset.
Whenever the redirect steps are applied, follow this set of steps:
Let original URL be the request URL.
Let request URL be the
URL conveyed by
the Location
header in the redirect response.
If the request URL <scheme> is not supported, infinite loop precautions are violated, or the user agent does not wish to make the new request for some other reason, apply the network error steps.
If the request URL contains the
userinfo
production apply the
network error steps.
If the resource sharing check for the current resource returns fail, apply the network error steps.
If the request URL
origin is not
same origin with the
original URL origin, set
source origin to a globally unique identifier (becomes
"null
" when transmitted).
Transparently follow the redirect while observing the set of request rules.
Whenever the abort steps are applied, terminate the algorithm that invoked this set of steps and set the cross-origin request status to abort error.
Whenever the network error steps are applied, terminate the algorithm that invoked this set of steps and set the cross-origin request status to network error.
This has no effect on setting of user credentials. I.e. if the block cookies flag is unset, cookies will be set by the response.
Whenever the cache and network error steps are applied, follow these steps:
Remove the entries in the preflight result cache where origin field value is a case-sensitive match for source origin and url field value is a case-sensitive match for request URL.
Apply the network error steps acting as if the algorithm that invoked the cache and network error steps invoked the network error steps instead.
There is a cache match when there is a cache entry in the preflight result cache for which the following is true:
The origin field value is a case-sensitive match for source origin.
The url field value is a case-sensitive match for request URL.
The credentials field value is true and the omit credentials flag is unset, or it is false and the omit credentials flag is set.
There is a method cache match when there is a cache entry for which there is a cache match and the method field value is a case-sensitive match for the given method.
There is a header cache match when there is a cache entry for which there is a cache match and the header field value is an ASCII case-insensitive match for the given header field name.
The resource sharing check algorithm for a given resource is as follows:
If the response includes zero or more than one
Access-Control-Allow-Origin
header values, return fail and terminate this algorithm.
If the
Access-Control-Allow-Origin
header value is the "*
" character and the
omit credentials flag is set, return pass and terminate this
algorithm.
If the value of
Access-Control-Allow-Origin
is not a case-sensitive match for the value of the
Origin
header as defined by its
specification, return fail and terminate this algorithm.
If the omit credentials flag is unset and the response
includes zero or more than one
Access-Control-Allow-Credentials
header values, return fail and terminate this algorithm.
If the omit credentials flag is unset and the
Access-Control-Allow-Credentials
header value is not a case-sensitive match for
"true
", return fail and terminate this algorithm.
Return pass.
The above algorithm also functions when the
ASCII serialization of an origin is
the string "null
".
This section is non-normative.
At various places user agents are allowed to take additional precautions. E.g. user agents are allowed to not store cache items, remove cache items before they reached their max-age, and not connect to certain URLs.
User agents are encouraged to impose a limit on max-age so items cannot stay in the preflight result cache for unreasonable amounts of time.
As indicated as the first step of the cross-origin request algorithm and in the redirect steps algorithm user agents are allowed to terminate the algorithm and not make a request. This could be done because e.g.:
https
to http
is not allowed.https
is not allowed because of certificate errorsUser agents are encouraged to apply security decisions on a generic
level and not just to the resource sharing policy. E.g. if a user agent
disallows requests from the https
to the http
scheme for a cross-origin request it is encouraged to do the
same for the HTML img
element.
This section is non-normative.
This specification defines a resource sharing policy that cannot be implemented without an API that utilizes it. The specification that defines the API that uses the policy is a CORS API specification.
In case a CORS API specification defines multiple APIs that utilize the policy the advice is to be considered separately for each API.
For all cross-origin requests that APIs can make for which the resource sharing policy in this specification is supposed to apply, the CORS API specification needs to reference the cross-origin request algorithm and set the following input variables appropriately: request URL, request method, author request headers, request entity body, source origin, manual redirect flag, omit credentials flag, and the force preflight flag.
CORS API specifications are allowed to let these input variables be controlled by the API, but can also set fixed values.
A CORS API specification for an API that only allows
requests using the GET
method might set
request method to GET
,
request entity body to empty, and source origin
to some appropriate value and let the other variables be controlled by the
API.
Since browsers are based on a same origin security model and the policy outlined in this specification is intended for APIs used in browsers, it is expected that APIs that will utilize this policy will have to handle a same origin request that results in a redirect that is cross-origin in a special way.
For APIs that transparently handle redirects CORS API specifications are encouraged to handle this scenario transparently as well by "catching" the redirect and invoking the cross-origin request algorithm on the (cross-origin) redirect URL.
The XMLHttpRequest specification does this. [XHR]
While a cross-origin request is progressing its associated cross-origin request status is updated. Depending on the value of the cross-origin request status the API is to react in a different way:
Features that can only be safely exposed after a preflight request can now be enabled.
E.g. upload progress events for
XMLHttpRequest
.
The contents of the response can be shared with the API, including headers that have not been filtered out.
The request itself can still be progressing. I.e. the cross-origin request status value does not indicate that the request has completed.
Handle analogous to requests where the user aborted the request. This can be handled equivalently to how network error is handled. Ensure not to reveal any further information about the request.
Handle analogous to requests where some kind of error occurred. Ensure not the reveal any further information about the request.
Similarly to same origin requests, CORS API specifications are encouraged to properly limit headers, methods, and user credentials the author can set and get for requests that are cross-origin.
Reviewing the XMLHttpRequest specification provides a good start for the kind of limitations that are to be imposed. [XHR]
CORS API specifications also need to ensure not to reveal anything until the cross-origin request status is set to preflight complete or success to prevent e.g. port scanning.
In XMLHttpRequest progress events are dispatched only after the cross-origin request status is set to success. Upload progress events are only dispatched once the cross-origin request status is preflight complete.
This appendix is non-normative.
The editor would like to thank Adam Barth, Alexey Proskuryakov, Arne Johannessen, Arthur Barstow, Benjamin Hawkes-Lewis, Bert Bos, Björn Höhrmann, Boris Zbarsky, Brad Hill, Cameron McCormack, Collin Jackson, David Håsäther, David Orchard, Dean Jackson, Eric Lawrence, Frank Ellerman, Frederick Hirsch, Graham Klyne, Hal Lockhart, Henri Sivonen, Ian Hickson, Jesse M. Heines, Jonas Sicking, Julian Reschke, Lachlan Hunt, 呂康豪 (Kang-Hao Lu), Maciej Stachowiak, Marc Silbey, Marcos Caceres, Mark Nottingham, Mark S. Miller, Martin Dürst, Matt Womer, Mhano Harkness, Michael Smith, Mohamed Zergaoui, Nikunj Mehta, Odin Hørthe Omdal, Philip Jägenstedt, Sharath Udupa, Simon Pieters, Sunava Dutta, Surya Ismail, Thomas Roessler, Tyler Close, Jeff Hodges, Vladimir Dzhuvinov, Wayne Carr, and Zhenbin Xu for their contributions to this specification.
Special thanks to Brad Porter, Matt Oshry and R. Auburn, who all helped editing earlier versions of this document.