W3C

Cross-Origin Resource Sharing

W3C Working Draft 17 March 2009

This Version:
http://www.w3.org/TR/2009/WD-cors-20090317/
Latest Version:
http://www.w3.org/TR/cors/
Latest Editor Version:
http://dev.w3.org/2006/waf/access-control/
Previous Versions:
http://www.w3.org/TR/2008/WD-access-control-20080912/
http://www.w3.org/TR/2008/WD-access-control-20080214/
http://www.w3.org/TR/2007/WD-access-control-20071126/
http://www.w3.org/TR/2007/WD-access-control-20071001/
http://www.w3.org/TR/2007/WD-access-control-20070618/
http://www.w3.org/TR/2007/WD-access-control-20070215/
http://www.w3.org/TR/2006/WD-access-control-20060517/
http://www.w3.org/TR/2005/NOTE-access-control-20050613/
Editor:
Anne van Kesteren (Opera Software ASA) <annevk@opera.com>

Abstract

This document defines a mechanism to enable client-side cross-origin requests. Specifications that want to enable cross-origin requests in an API they define 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.

Status of this Document

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/.

This is the 17 March 2009 Working Draft of the "Cross-Origin Resource Sharing" document. It is expected that this document will progress along the W3C Recommendation track. This document is produced by the Web Applications (WebApps) Working Group. The WebApps Working Group is part of the Rich Web Clients Activity in the W3C Interaction Domain.

This draft was also known as "Access Control for Cross-Site Requests", "Enabling Read Access for Web Resources", and "Authorizing Read Access to XML Content Using the <?access-control?> Processing Instruction 1.0" in reverse chronological order.

Please send comments to the WebApps Working Group's public mailing list public-webapps@w3.org with [cors] at the start of the subject line. Archives of this list are available. See also W3C mailing list and archive usage guidelines.

This document was produced by a group 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.

Publication as a Working Draft 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.

Table of Contents

1 Introduction

This section is non-normative.

Web application technologies 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 the amount of unsafe HTTP requests that can be automatically launched toward destinations that differ from the running application's origin.

In Web application technologies that follow this pattern, network requests typically use ambient authentication and session management information, including HTTP authentication and cookie information.

This specification extends this model in several ways:

This specification is a building block for other specifications, so-called hosting specifications, which will define the precise model by which this specification is used. Among others, such specifications are likely to include XMLHttpRequest Level 2, XBL 2.0, and HTML 5.

The design of this specification introduces is based on requirements and use cases, both included as appendix. A FAQ describing the design decisions is also available.

If a server 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 resource 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 resource on http://hello-world.example can access this document as follows:

new client = new XMLHttpRequest();
client.open("GET", "http://example.com/hello")
client.onreadystatechange = function() { /* do something */ }
client.send()

It gets slightly more complicated if the server 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)
}

XMLHttpRequest Level 2 includes support for cross-origin requests.

2 Conformance Criteria

This specification is written for servers and user agents. It includes advice for specifications that define APIs that use the resource sharing policy defined in this specification — hosting 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 server is one that implements all the requirements listed in this specification that are applicable to servers.

A conformant user agent is one that implements all the requirements listed in this specification that are applicable to user agents.

User agents 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.

2.1 Terminology

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 .. U+005A (i.e. LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z) and the corresponding characters in the range U+0061 .. U+007A (i.e. LATIN SMALL LETTER A to LATIN SMALL LETTER Z) are considered to also match.

Converting a string to lowercase means replacing all characters in the range U+0041 .. U+005A (i.e. LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z) with the corresponding characters in the range U+0061 .. U+007A (i.e. LATIN SMALL LETTER A to LATIN SMALL LETTER Z).

The terms URL, origin, ASCII serialization of an origin, and same origin are defined by HTML 5. [HTML5]

The term cross-origin is used to mean non same origin.

The productions delta-seconds, Method, and field-name are defined in RFC 2616. [RFC2616]

A method is said to be a simple method if it is a case-sensitive match for one of the following methods:

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.

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.

3 Security Considerations

This section is non-normative.

Security requirements and considerations are listed throughout this specification. This section lists advice that did not fit anywhere else.


Authors of client-side Web applications are strongly encouraged to validate content retrieved from a cross-origin resource as it might be harmful.

Authors of client-side Web applications using a URL of the type people.example.org/~author-name/ are to be aware that only cross-origin security is provided and that therefore using a distinct origin rather than distinct path is vital for secure client-side Web applications.

4 Syntax

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 server processing model section details how servers are to use these headers. 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 RFC 2616. [RFC2616]

RFC 2616 is used as ABNF basis to ensure that the new headers have equivalent parsing rules to those introduced in that specification.

4.1 Access-Control-Allow-Origin Response Header

The Access-Control-Allow-Origin header indicates which origin a resource it is specified for can be shared with. ABNF:

Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" source origin string | "*"

4.2 Access-Control-Max-Age Response Header

The 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

4.3 Access-Control-Allow-Credentials Response Header

The Access-Control-Allow-Credentials header indicates whether the response to request can be exposed when the credentials flag is true. When part of the response to a preflight request it indicates that the actual request can be made with credentials. ABNF:

Access-Control-Allow-Credentials: "Access-Control-Allow-Credentials" ":" "true"

4.4 Access-Control-Allow-Methods Response Header

The 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

4.5 Access-Control-Allow-Headers Response Header

The 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

4.6 Origin Request Header

The Origin header indicates where the cross-origin request or preflight request originates from. ABNF:

Origin = "Origin" ":" source origin string

The source origin string can be the string "null". When the source originates from a data: URL for instance.

In contrast with the Referer header, Origin does not reveal confidential path information and does therefore not need to be disabled.

4.7 Access-Control-Request-Method Request Header

The 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

4.8 Access-Control-Request-Headers Request Header

The 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

5 Server Processing Model

This section describes the processing models that servers have to implement. Each type of request a server might have to deal with is described in its own subsection.

The resource sharing policy described by this specification is bound to a particular URL. For the purposes of this section each URL is bound to the following:

5.1 Simple Cross-Origin Request and Actual Request

In response to a simple cross-origin request or actual request the server indicates whether or not to share the URL.

Servers must use the following set of steps to determine which additional headers to use in the response:

  1. 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.

  2. If the URL 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 literal string "true" as value.

    Otherwise, add a single Access-Control-Allow-Origin header, with either the value of the Origin header or the literal string "*" as value.

By failing this request servers 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 URL.

5.2 Preflight Request

In response to a preflight request the server indicates which methods and headers (other than simple methods and simple headers) it is willing to handle and whether a request with credentials is allowed for the URL.

Servers must use the following set of steps to determine which additional headers to use in the response:

  1. 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.

  2. 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.

  3. Let headers be the values as result of parsing the Access-Control-Request-Headers headers.

    If there are no Access-Control-Request-Headers headers let headers be the empty list.

    If parsing failed do not set any additional headers and terminate this set of steps.

  4. 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.

  5. If any of the headers 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.

  6. If the URL 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.

  7. 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.

  8. 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.

  9. If each of the headers is a simple header 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 it does not need to be listed, but this is not prohibited.

    Since the list of headers can be unbounded simply returning headers can be enough.

5.3 Security

This section is non-normative.

Servers 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 servers 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, servers 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. This will provide protection against DNS rebinding attacks.

To provide integrity protection of resource sharing policy statements usage of SSL/TLS is encouraged.

6 User Agent Processing Model

This section describes the processing models that user agents have to implement.

The processing models in this sections are typically referenced by a hosting 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.

Everything with regards to redirects might change a little to more closely adhere to HTTP redirect semantics.

6.1 Cross-Origin Request

The cross-origin request algorithm takes the following parameters:

request URL

The URL for the request.

The request URL is modified in face of redirects.

request method

The method for the request.

custom request headers

A list of custom headers for the request.

request entity body

The entity body for the request.

source origin

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.

credentials flag

Whether or not to include credentials for the request.

force preflight flag

Whether or not to force a preflight request for the request.

The return values are described further down. The cross-origin request algorithm can be used by hosting specifications who wish to allow cross-origin requests for the network APIs they define.

Hosting specifications are free to limit the abilities of a cross-origin request. E.g., the credentials flag could always be false.

When the cross-origin request algorithm is invoked, these steps must be followed:

  1. If for some reason the user agent does not want to make the request terminate this algorithm and return with the status flag set to network.

    E.g. the request URL could have been blacklisted by the user in some fashion.

  2. If the force preflight flag is false and the following conditions are all true, follow the simple cross-origin request algorithm:

  3. Otherwise, follow the cross-origin request with preflight algorithm.

Cross-origin requests using a method that is simple with custom request headers that are not simple will have a preflight request to ensure that the server 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 an ASCII case-insensitive match for one of the header field names listed below, before exposing response headers to the APIs defined in the hosting specification:

E.g. the getResponseHeader() method of XMLHttpRequest will therefore not expose any header not listed above.

The output of a cross-origin request is the status flag. The status flag indicates the status of the cross-origin request. It takes the value success when cross-origin access to the resource is allowed, network if a network error of some sort occurred, and abort if the user aborted the request.

6.1.1 Source Origin

The source origin string is the ASCII serialization of the source origin.

In addition to following the requirements for cross-origin requests, user agents must set the Origin header value to the source origin string for each request (including redirects).

6.1.2 Simple Cross-Origin Request

The steps below describe what user agents must do for a simple cross-origin request:

  1. Apply the make a request steps and observe the request rules below while making the request.

    If the response is an HTTP redirect

    Apply the redirect steps.

    If the user cancels the request

    Apply the abort steps.

    If there is a network error

    Apply the network error steps.

    Otherwise

    Perform a resource sharing check. If it returns fail, apply the network error steps. Otherwise, if it returns pass, terminate this algorithm and return with the status flag set to success. Do not actually terminate the request.

6.1.3 Cross-Origin Request with Preflight

To protect servers against cross-origin access with methods that have side effects an preflight request is made to ensure that the server is ok with the request. The result of this request is stored in an 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 need to be authorized using either a preflight result cache entry or a preflight request.

  1. Go to the next step if the following conditions are true:

    Otherwise, make a preflight request. This is a request using the method OPTIONS to the request URL with the normal request headers and the following additional constraints:

    The following request rules are to be observed while making this request:

    If the response is an HTTP redirect

    Apply the redirect steps.

    If the user cancels the download

    Apply the abort steps.

    If there is a network error

    Apply the network error steps.

    The cache and network error steps are not used here as this is about an actual network error.

    Otherwise
    1. If the resource sharing check returns fail, apply the cache and network error steps.

    2. Let methods be the empty list.

    3. 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.

    4. Let headers be the empty list.

    5. 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.

    6. 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.

    7. If the field name of each header in custom 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.

    8. 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).

    9. 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.

    10. 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:

      origin
      The source origin string.
      url
      The request URL.
      max-age
      The max-age.
      credentials
      The credentials flag.
      method
      The given method.
      header
      Empty.
    11. 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:

      origin
      The source origin string.
      url
      The request URL.
      max-age
      The max-age.
      credentials
      The credentials flag.
      method
      Empty.
      header
      The given header.
  2. This is the actual request. Apply the make a request steps and observe the request rules below while making the request.

    If the response is an HTTP redirect

    Apply the cache and network error steps.

    If the user cancels the download

    Apply the abort steps.

    If there is a network error

    Apply the network error steps.

    Otherwise

    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 return with the status flag set to success. Do not actually terminate the request.

Consider the following scenario:

  1. 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.

  2. 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.

  3. 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
  4. 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.

6.1.4 Preflight Result Cache

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:

origin
Holds the source origin string.
url
Holds the request URL.
max-age
Holds the Access-Control-Max-Age header value.
credentials
Holds the value of the credentials flag.
method
Empty if header is not empty; otherwise one of the values from the Access-Control-Allow-Methods headers.
header
Empty if method is not empty; otherwise one of the values from the 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.

6.1.5 Generic Cross-Origin Request Algorithms

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, make a request to request URL, using method request method, entity body request entity body, including the custom request headers, and include credentials if the credentials flag is true (e.g. HTTP authentication data and cookies).

Whenever the redirect steps are applied, follow this set of steps:

  1. Let request URL be the new URL.

  2. If the new 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 and terminate this set of steps.

  3. If the request URL contains the userinfo production, as defined in section 3.2.1 of RFC 3986, apply the network error steps. [RFC3986]

  4. If the resource sharing check for the current resource returns fail, apply the generic network steps.

  5. Otherwise, transparently follow the redirect while observing the set of request rules.

A redirect to a URL that is same origin with the source origin is handled identically to any other URL.


Whenever the abort steps are applied, terminate the algorithm that invoked this set of steps and return with the status flag set to abort.


Whenever the network error steps are applied, terminate the algorithm that invoked this set of steps and return with the status flag set to network.

Whenever the cache and network error steps are applied, follow this set of steps:

  1. Remove the entries in the preflight result cache where origin field value is a case-sensitive match for source origin string and url field value is a case-sensitive match for request URL.

  2. 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:

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.

6.2 Resource Sharing Check

The resource sharing check algorithm for a given resource is as follows:

  1. If the resource includes zero or more than one Access-Control-Allow-Origin headers return fail and terminate this algorithm.

  2. If the Access-Control-Allow-Origin header value is the literal "*" character and the credentials flag is false return pass and terminate this algorithm.

  3. If the value of Access-Control-Allow-Origin is not a case-sensitive match for the source origin string return fail and terminate this algorithm.

  4. If the credentials flag is true and the resource includes zero or more than one Access-Control-Allow-Credentials headers return fail and terminate this algorithm.

  5. If the credentials flag is true and the Access-Control-Allow-Credentials header value is not a case-sensitive match for "true" return fail and terminate this algorithm.

  6. Return pass.

The above algorithm also functions when the ASCII serialization of an origin is the string "null".

6.3 Security

This section is non-normative.

User agents are to carefully follow the rules set forth in the preceding sections to prevent introducing new attack vectors.

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.:

User 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.

7 Hosting Specification Advice

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 an hosting specification.

In case an hosting specification defines multiple APIs that utilize the policy the advice is to be considered separately for each API.

7.1 Constructing a Cross-Origin Request

For all requests APIs can make that are cross-origin for which the resource sharing policy in this specification is supposed to apply the hosting specification needs to reference the cross-origin request algorithm and set the following input variables appropriately: request URL, request method, custom request headers, request entity body, source origin, credentials flag, and the force preflight flag.

Hosting specifications are allowed to let these input variables be controlled by the API, but can also set fixed values.

A hosting 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.

7.2 Dealing with Same Origin to Cross-Origin Redirects

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 hosting 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 network API does this.

7.3 Dealing with the Status Flag

When a cross-origin request is finished (the request itself is still progresing) a status flag is returned. Depending on the value of the status flag the API is to react in a different way:

abort

Handle analogous to requests where the user aborted the request. This can be handled equivalently to how network is handled. Ensure not to reveal any further information about the request.

network

Handle analogous to requests where some kind of error occured. Ensure not the reveal any further information about the request.

success

The contents of the resource can be shared with the API, including headers that have not been filtered out.

In case of network the request itself can still be progressing. I.e. this status flag value does not indicate that the request has completed.

7.4 Security

Similarly to same origin requests, hosting specifications are encouraged properly limit headers, methods, and credential data the author can set and get for requests that are cross-origin.

Reviewing the XMLHttpRequest Level 2 specification provides a good start for the kind of limitations that are to be imposed.

Hosting specifications also need to ensure not to reveal anything until the status flag is set to success to prevent e.g. port scanning.

In XMLHttpRequest Level 2 progress events are dispatched only after the status flag is set to success.

Requirements

This appendix is non-normative.

This appendix outlines the various requirements that influenced the design of the Cross-Origin Resource Sharing specification.

  1. Must not introduce attack vectors to servers that are only protected only by a firewall.

  2. The solution should not introduce additional attack vectors against services that are protected only by way of firewalls. This requirement addresses "intranet" style services authorize any requests that can be sent to the service.

    Note that this requirement does not preclude HEAD, OPTIONS, or GET requests (even with ambient authentication and session information).

  3. It should not be possible to perform cross-origin non-safe operations, i.e., HTTP operations except for GET, HEAD, and OPTIONS, without an authorization check being performed.

  4. Should try to prevent dictionary-based, distributed, brute-force attacks that try to get login accounts to 3rd party servers, to the extent possible.

  5. Should properly enforce security policy in the face of commonly deployed proxy servers sitting between the user agent and any of servers with whom the user agent is communicating.

  6. Should not allow loading and exposing of resources from 3rd party servers without explicit consent of these servers as such resources can contain sensitive information.

  7. Must not require content authors or site maintainers to implement new or additional security protections to preserve their existing level of security protection.

  8. Must be deployable to IIS and Apache without requiring actions by the server administrator in a configuration where the user can upload static files, run serverside scripts (such as PHP, ASP, and CGI), control headers, and control authorization, but only do this for URLs under a given set of subdirectories on the server.

  9. Must be able to deploy support for cross-origin GET requests without having to use server-side scripting (such as PHP, ASP, or CGI) on IIS and Apache.

  10. The solution must be applicable to arbitrary media types. It must be deployable without requiring special packaging of resources, or changes to resources' content.

  11. It should be possible to configure distinct cross-origin authorization policies for different target resources that reside within the same origin.

  12. It should be possible to distribute content of any type. Likewise, it should be possible to transmit content of any type to the server if the API in use allows such functionality.

  13. It should be possible to allow only specific servers, or sets of servers to fetch the resource.

  14. Must not require that the server filters the entity body of the resource in order to deny cross-origin access to all resources on the server.

  15. Cross-origin requests should not require API changes other than allowing cross-origin requests. This means that the following examples should work for resources residing on http://test.example (modulo changes to the respective specifications to allow cross-origin requests):

  16. It should be possible to issue methods other than GET to the server, such as POST and DELETE.

  17. Should be compatible with commonly used HTTP authentication and session management mechanisms. I.e. on an IIS server where authentication and session management is generally done by the server before ASP pages execute this should be doable also for requests coming from cross-origin requests. Same thing applies to PHP on Apache.

  18. Should reduce the risk of inadvertently allowing access when it is not intended. This is, it should be clear to the content provider when access is granted and when it is not.

Use Cases

This appendix is non-normative.

The main motivation behind Cross-Origin Resource Sharing was to remove the same origin restriction from various APIs so that resources can be shared among different origins (i.e. servers).

Here are various APIs that might make use of the functionality described in this specification to allow cross-origin requests:

Design Decision FAQ

This appendix is non-normative.

This appendix documents several frequently asked questions and their corresponding response.

Why is there a preflight request?

For most type of requests two resource sharing checks are performed. Initially a "permission to make the request" check is done on the response to the preflight request. And then a "permission to read" check is done on the response to the actual request. Both of these checks need to succeed in order for success to be relayed to the API (e.g. XMLHttpRequest).

The "permission to make the request" check is performed because deployed servers do not expect such cross-origin requests. E.g., a request using the HTTP DELETE method. If they reply positively to the preflight request the client knows it can go ahead and perform the actual desired request.

Why is POST treated similarly to GET?

Cross-origin POST requests have long been possible using the HTML form element. However, this is only the case when Content-Type is set to one of the media types allowed by HTML forms.

Why are cookies and authentication information sent in the request?

Sending cookies and authentication information enables user-specific cross-origin widgets (external XBL file). It also allows for a user authenticated data storage API that services can use to store data in.

Cookies and authentication information is already sent cross-origin for various HTML elements, such as img, script, and form.

This specification does allow for APIs that use the resource sharing policy to not send cookies or authentication information by means of the credentials flag.

Why can cookies and authentication information not be provided by the script author for the request?

This would allow dictionary based, distributed, cookies / user credentials search.

Why is the client the policy enforcement point?

The client already is the policy enforcement point for these requests. The mechanism allows the server to opt-in to let the client expose the data. Something clients currently not do and which servers rely upon.

Note however that the server is in full control. Based on the value of the Origin header in cross-origin requests it can decide to return no data at all or not provide the necessary handshake (the Access-Control-Allow-Origin header).

What about the JSONRequest proposal?

JSONRequest has been considered by the Web Applications Working Group and the group has concluded that it does not meet the documented requirements. JSONRequest is a specific API and cannot handle e.g. cross-origin XSLT through <?xml-stylesheet?> or the same scenarios same-origin XMLHttpRequest can handle today in cross-origin fashion, e.g. manipulating resources making use of the REST architectural style.

References

[HTML5]
HTML 5 (work in progress), I. Hickson, D. Hyatt, editors. W3C, 2009.
HTML 5 (work in progress), I. Hickson, editor. WHATWG, 2009.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF, March 1997.
[RFC2616]
Hypertext Transfer Protocol -- HTTP/1.1, R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee, editors. IETF, June 1999
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax, T. Berners-Lee, R. Fielding, L. Masinter, editors. IETF, January 2005.

Acknowledgments

This appendix is non-normative.

The editor would like to thank Adam Barth, Alexey Proskuryakov, Arthur Barstow, Benjamin Hawkes-Lewis, Björn Höhrmann, 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, Jonas Sicking, Lachlan Hunt, Maciej Stachowiak, Marc Silbey, Marcos Caceres, Mark Nottingham, Martin Dürst, Matt Womer, Michael Smith, Mohamed Zergaoui, Nikunj Mehta, Sharath Udupa, Sunava Dutta, Surya Ismail, Thomas Roessler, Tyler Close, 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.