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.

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.

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.

A resource 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 are enabled to discover whether a cross-origin resource is
prepared to accept requests using a non-GET 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
on the cross-origin requests that they are willing to service.

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.

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:

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:

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:

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

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.

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.

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:

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.

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.

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:

Cache-Control

Content-Language

Content-Type

Expires

Last-Modified

Pragma

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

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 originhttp://example.org
to http://blog.example/entries/hello-world.

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.

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.

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.

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.

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

The server is blacklisted.

The server is known to be part of an intranet.

The URL <scheme> is not supported.

https to http is not allowed.

https to https is not allowed because e.g.
the certificates differ.

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.

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.

7.3 Dealing
with the Status Flag

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.

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

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

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.

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

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.

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.

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

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.

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.

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

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

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.

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

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.

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

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

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.

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:

The XMLHttpRequest network API might make use of the
resource sharing policy to allow client-side access to a database on a
separate server which can be interacted with through HTTP.

A server foo.example.org might implement an HTTP API to
allow authenticated users to edit resources on that server. Thanks to
the resource sharing policy users of a client-side editing application
on server editing.example that are authenticated with
foo.example.org can then edit their resources directly
without any workarounds or intermediaries. (The application uses
XMLHttpRequest for network traffic.)

A server calendar.example could expose a simple HTTP API
that allows incoming requests using the PUT method when the
user is authenticated with the server. Every time a trusted server
issues such a request using XMLHttpRequest a new calendar
entry is queued.

HTML 5 defines an eventsource element and associated
API. It is expected it will make use of the resource sharing policy so
that the server streaming the events can be separate from the server
hosting the page or application.

E.g. a service such as a news or stock ticker can be on a central
server and shared with many other servers.

The xml-stylesheet processing instruction does not allow
cross-origin loads to prevent data theft
(e.g., from intranets). Thanks to the resource sharing policy several
servers can share a single XSLT resource.

An XBL binding allows the document to which it is bound to have full
access to the document in which it is defined. To prevent data theft cross-origin XBL usage is therefore prohibited.
The resource sharing policy enables cross-origin XBL bindings. If the user is
authenticated with the server that hosts the XBL widget it is possible
to have a user-specific cross-origin
bindings.

The CSS @font-face construct prohibits cross-origin loads. With the resource sharing
policy someone could set up a Web service that sells font licenses to
selected servers and handles caching and bandwidth usage for them.

Design Decision FAQ

This appendix is non-normative.

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

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?

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.