이 문서는 Cross-Origin Resource Sharing의 한국어 번역 문서입니다.
번역을 진행 중이며 2016년 5월 15일까지는 완료 예정입니다.
번역으로 인한 오류가 존재할 수 있기 때문에 반드시 원문도 확인하시길 바랍니다.

번역자:
조은 <apes0123@gmail.com>

W3C

크로스 오리진 리소스 공유 (Cross-Origin Resource Sharing)

2014년 1월 16일 W3C 권고안

이 버전:
http://www.w3.org/TR/2014/REC-cors-20140116/
마지막 버전:
http://www.w3.org/TR/cors/
이전 버전:
http://www.w3.org/TR/2013/PR-cors-20131205/
http://www.w3.org/TR/2013/CR-cors-20130129/
http://www.w3.org/TR/2012/WD-cors-20120403/
http://www.w3.org/TR/2010/WD-cors-20100727/
http://www.w3.org/TR/2009/WD-cors-20090317/
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/
작성자:
Anne van Kesteren (formerly of Opera Software ASA) <annevk@annevk.nl>

이 문서의 errata를 확인하시기 바랍니다.

이 스펙 문서의 표준은 영문 버전만 존재합니다. 표준이 아닌 번역본이 존재할 수도 있습니다. 이 번역본은 한국어 번역본 입니다


요약

이 문서는 클라이언트에서 크로스 오리진 요청(cross-origin requests)을 가능하게 하는 메커니즘을 정의합니다. 이 스펙에 의해 정의된 알고리즘을 이용해 리소스를 크로스 오리진 요청할 수 있게 하는 API 스펙입니다. 만약 API를 http://example.org 리소스에서 사용하고, 리소스는 http://hello-world.example에 있다고 하면, 이 스펙문서에서 소개하는 메커니즘을 선택하여 사용하여(예를 들어, Access-Control-Allow-Origin: http://example.org를 응답 헤더로 둡니다), http://example.org에서 크로스 오리진으로 리소스를 가져올 수 있습니다.

이 문서의 상태

이 섹션은 이 문서를 공개했을 때 상태에 대해 설명합니다. 다른 문서가 이 문서를 덮어쓸 가능성이 있으니 주의하시길 바랍니다. 이 문서 및 W3C에서 공개한 다른 문서의 최신 버전은 W3C technical reports index at http://www.w3.org/TR/에서 확인 가능합니다.

이 문서는 W3C 멤버, 소프트웨어 개발자, 그리고 다른 W3C 그룹 및 관계자들이 평가를 진행하여, 디렉터에 의해 W3C 권고안으로 발표했습니다. 이 문서는 안정적이며, 참고자료로 사용하거나 다른 문서에서 인용해도 좋습니다. 스펙 문서의 권고를 통해 W3C가 하는 역할은 스펙 문서에 관심을 모으고 다방면으로 퍼뜨리는 일입니다. 이를 통해 웹의 기능과 상호운용성 향상을 기대할 수 있습니다.

이 CORS W3C 권고안은 Web Applications (WebApps)와 Web Application Security 워킹 그룹에서 주로 관리하며, WebAppSec 워킹그룹에 의해 발행되었습니다. 이전 후보 권고안 발행 버전과 차이점은 없습니다.

만약 이 문서에 대한 코멘트를 남기고 싶다면, public-webappsec@w3.org (subscribe, archives)으로 보내주시길 바랍니다.

이 문서는 2004년 2월 6일 W3C 특허 정책을 따르는 그룹에서 작성하였습니다. W3C는 그룹의 성과물에 관련하여 모든 공개 특허 공개 리스트를 관리합니다. 여기에는 특허 공개에 대한 지시사항도 포함합니다. 특허에 대해서 충분한 지식이 있는 사람이, 스펙 문서의 Essential Claim(s)에 인정된다고 파악되는 경우, W3C 특허 정책 제 6장에 의거하여 정보를 공개해야 할 필요가 있습니다.

이 권고안을 발행함으로써 W3C는 이 권고안 내 정의된 기능들이 HTML5나 HTTP Status Code 308이 권고안 및 RFC 상태 진행으로 인해 내용이 변경되더라도 영향을 받지 않을 거라 기대하고 있습니다.

예비 권고안부터 변경사항을 포함한 구현보고서를 사용할 수 있습니다.

목차

  1. 1 소개
  2. 2 적합 요구사항
  3. 3 용어
  4. 4 보안 고려사항
  5. 5 문법
    1. 5.1 Access-Control-Allow-Origin 응답 헤더
    2. 5.2 Access-Control-Allow-Credentials 응답 헤더
    3. 5.3 Access-Control-Expose-Headers 응답 헤더
    4. 5.4 Access-Control-Max-Age 응답 헤더
    5. 5.5 Access-Control-Allow-Methods 응답 헤더
    6. 5.6 Access-Control-Allow-Headers 응답 헤더
    7. 5.7 Origin 요청 헤더
    8. 5.8 Access-Control-Request-Method 요청 헤더
    9. 5.9 Access-Control-Request-Headers 요청 헤더
  6. 6 Resource Processing Model
    1. 6.1 Simple Cross-Origin Request, Actual Request, and Redirects
    2. 6.2 Preflight Request
    3. 6.3 Security
    4. 6.4 Implementation Considerations
  7. 7 User Agent Processing Model
    1. 7.1 Cross-Origin Request
      1. 7.1.1 Handling a Response to a Cross-Origin Request
      2. 7.1.2 Cross-Origin Request Status
      3. 7.1.3 Source Origin
      4. 7.1.4 Simple Cross-Origin Request
      5. 7.1.5 Cross-Origin Request with Preflight
      6. 7.1.6 Preflight Result Cache
      7. 7.1.7 Generic Cross-Origin Request Algorithms
    2. 7.2 Resource Sharing Check
    3. 7.3 Security
  8. 8 CORS API Specification Advice
    1. 8.1 Constructing a Cross-Origin Request
    2. 8.2 Dealing with Same Origin to Cross-Origin Redirects
    3. 8.3 Dealing with the Cross-Origin Request Status
    4. 8.4 Security
  9. References
  10. Acknowledgments

1 소개

이 섹션은 표준에 준하지 않습니다.

유저 에이전트는 보통 네트워크 요청에서 동일 오리진 제한(same-origin restrictions)을 적용합니다. 이로 인해 특정 오리진 클라이언트측 웹 어플리케이션이 다른 출처의 데이터를 검색하는 걸 제한하고 현재 실행 중인 어플리케이션의 오리진과 다른 안전하지 않은 HTTP 요청이 자동으로 발신하는 걸 제한합니다.

위 패턴을 따르는 유저 에이전트는, HTTP 인증, cookie 정보 등 사용자의 자격 증명이 포함된 전형적 네트워크 요청이 있습니다.

이 스펙에서는 이 모델을 다양한 방법으로 확장합니다:

이 스펙문서에서는 이 스펙 문서가 어떻게 사용되어야 하는 지 정의하는, 소위 CORS API 스펙문서이며, 다른 스펙을 위한 소재(building block)입니다. 예로는 Server-Sent Events와 XMLHttpRequest가 있습니다. [EVENTSOURCE] [XHR]

CORS 위키 페이지는 이 문서에 대한 더 많은 배경 지식을 제공합니다.

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

2 적합 요구사항

이 스펙문서는 리소스 작성자와 유저 에이전트를 위해 작성했습니다. 이 스펙문서 내에서 정의하는 크로스 오리진 요청 알고리즘을 사용하는 API를 정의하는 스펙문서—CORS API 정의—를 위한 조언을 포함하며, 일반 보안 고려사항 섹션은 클라이언트 사이드 웹 어플리케이션 작성자를 위한 몇가지 조언을 포함하고 있습니다.

이 스펙문서 내에서 표준에 준하지 않는다 따로 표시한 섹션과 부록, 모든 다이어그램, 예제, 노트는 표준에 준하지 않습니다. 그 외는 모두 표준에 준합니다.

이 스펙문서에서, must와 may같은 단어는 RFC 2119에서 소개하는 대로 해석합니다. [RFC2119]

반드시 해야한다고 나타낸 알고리즘의 일부(예를 들어, "알고리즘을 종료") 요구사항은 알고리즘 소개에서 사용하는 키워드(예를 들어, must)의 의미로 해석해야합니다.

순응 리소스는 이 스펙문서에 나와있는 리소스에 적용할 수 있는 모든 요구사항을 구현하는 것입니다.

순응 유저 에이전트는 이 스펙문서에 나와있는 유저 에이전트에 적용할 수 있는 모든 요구사항을 구현하는 것입니다.

유저 에이전트와 리소스 작성자는 스펙문서의 알고리즘으로 얻어진 것인지 결과 구분이 안되는 동안에는, 이 스펙의 구현체의 임의의 알고리즘을 사용할 수 있습니다.

3 용어

이 스펙 문서 내의 몇가지 용어는 The Web Origin Concept, HTML, HTTP, URI에서 인용했습니다. [ORIGIN] [HTML] [HTTP] [URI]

용어는 이 스펙문서를 뛰어넘는 공용으로 정의되어있습니다. 그러나, 몇가지 정의는 어디에서나 사용할 때 여기서 정의한 것과 딱 맞지 않을 수도 있습니다.

대소문자 구분으로 두 문자열을 비교하는 건, 코드 포인트에서 코드 포인트를 정확하게 비교하는 걸 의미합니다.

ASCII 대소문자를 구분하지 않고 두 문자열을 비교하는 건, 코드 포인트에 대한 코드 포인트를 정확히 비교하지만, U+0041 라틴 대문자 A부터 U+005A 라틴 대문자 Z 범위와 U+0061 라틴 소문자 A부터 U+007A 라틴 소문자 Z에 해당하는 범위가 매치하는 것으로 간주된다는 걸 의미합니다.

ASCII 소문자 문자열 변환 은 U+0041 라틴 대문자 A부터 U+005A 라틴 대문자 Z까지 범위의 모든 문자가 U+0061 라틴 소문자 A부터 U+007A 라틴 소문자 Z까지 범위에 일치함을 나타냅니다.

이 스펙 문서의 목적상, 용어 사용자 자격증명은 오리진에서 동작하는 유저 에이전트의 이전 인터렉션을 기반으로 둔 쿠키, HTTP 인증, 클라이언트 사이드 SSL 인증을 의미합니다. 구체적으로는 프록시 인증 및 Origin 헤더를 참조하지 않습니다. [COOKIES]

용어 크로스 오리진same origin을 의미하는 용어가 아닙니다.

method는 아래 목록 중 하나에 대소문자 구분하여 일치하는 경우, 간단 메서드를 의미합니다.

header는 헤더 필드 명이 Accept, Accept-Language, Content-LanguageASCII 대소문자를 구분하지 않고 일치 하거나, Content-TypeASCII 대소문자를 구분하지 않고 일치하거나, (파라미터를 제외한) 헤더 필드 값 미디어 타입이 application/x-www-form-urlencoded, multipart/form-data, text/plainASCII 대소문자를 구분하지 않고 일치하는 경우 간단 헤더를 의미합니다.

header는 헤더 필드 명이 아래 목록 중 하나에 ASCII 대소문자를 구분하지 않고 일치하는 경우 간단 응답 헤더를 의미합니다.

헤더를 해석할 때 반드시 문법 섹션에서 ABNF 프로덕션에 해당하는 대로 해석해야만 합니다 만약 헤더가 프로덕션에 매치하지 않는 경우 헤더 해석 실패라 부릅니다.

4 보안 고려사항

이 섹션은 표준에 준하지 않습니다.

이 스펙 내 존재하는 보안 요구사항 및 고려사항을 리스팅해둔 내용입니다. 다른 곳에서는 적합하지 않는 부분을 이 섹션에서 조언합니다.


simple cross-origin request는, 이 스펙을 준수하지 않는 현재 배포된 유저 에이전트에 의해 생성 될 수 있는 것들에 적합하게 정의하고 있습니다. 이 스펙 외부에서 생성되는 Simple cross-origin requests(예를 들어, script의 결과로 GET이나 POST 혹은 cross-origin GET 요청을 이용한 cross-origin form 전송)는 유저 인증서를 포함하며, 이 스펙을 따르는 리소스는 항상 인증서를 사용하여 simple cross-origin requests를 대비하여 준비해야합니다.

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.

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

  2. A resource that is publicly accessible, with no access control checks, can always safely return an Access-Control-Allow-Origin header whose value is "*".

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

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

    1. Authorization for a request should be performed using only the intersection of the authority of the user and the requesting origin(s).

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

  2. Use of user credentials in a cross-origin request is appropriate when:

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

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

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

5 문법

이 섹션에서는 이 스펙문서에서 소개하는 새로운 헤더의 문법을 정의합니다. 또 각 헤더에서 사용하는 함수의 짧은 설명을 제공합니다.

리소스 처리 모델 섹션은 리소스가 어떻게 응답 안 헤더에서 사용하는 지 디테일을 소개합니다. 마찬가지로, 유저 에이전트 처리 모델 섹션은 리소스를 어떻게 헤더에서 사용하는 지 디테일을 소개합니다.

이 섹션에서 사용하는 ABNF 문법은 HTTP/1.1에서 가져왔습니다. [HTTP]

HTTP/1.1은 새로운 헤더가 해당 스펙에 도입된 것과 동등한 파싱 규칙이 되도록 ABNF를 사용합니다.

HTTP/1.1은 현재 헤더 값 정의에 상정 OWS를 이끌지 않지만, 그 형태는 가정합니다.

5.1 Access-Control-Allow-Origin 응답 헤더

Access-Control-Allow-Origin 헤더는 Origin 요청 헤더의 값, "*", 요청 내 "null" 반환을 기반으로 리소스가 공유 가능한 지 가리킵니다. ABNF:

Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" origin-list-or-null | "*"

실제 origin-list-or-null 생성은 더 제한적입니다. 오히려 스페이스로 나뉘어진 origins 목록보다, 단일 origin이나 문자열 "null" 중 하나를 허용합니다.

5.2 Access-Control-Allow-Credentials 응답 헤더

The 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

5.3 Access-Control-Expose-Headers Response Header

The 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

5.4 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

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

The `Allow` header is not relevant for the purposes of the CORS protocol. ABNF:

Access-Control-Allow-Methods: "Access-Control-Allow-Methods" ":" #Method

5.6 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

5.7 Origin Request Header

The Origin header indicates where the cross-origin request or preflight request originates from. [ORIGIN]

5.8 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

5.9 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

6 Resource Processing Model

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:

6.1 Simple Cross-Origin Request, Actual Request, and Redirects

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:

  1. If the Origin header is not present terminate this set of steps. The request is outside the scope of this specification.

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

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

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

6.2 Preflight Request

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:

  1. If the Origin header is not present terminate this set of steps. The request is outside the scope of this specification.

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

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

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

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

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

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

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

  9. 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 the method indicated by Access-Control-Request-Method (if supported) can be enough.

  10. If each of the header field-names is a simple header and none is Content-Type, 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 supported headers from Access-Control-Allow-Headers can be enough.

6.3 Security

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.

6.4 Implementation Considerations

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.

7 User Agent Processing Model

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.

7.1 Cross-Origin Request

The cross-origin request algorithm takes the following parameters:

request URL

The URL to be fetched.

The request URL is modified in face of redirects.

request method

The method for the request. GET, unless explicitly set.

author request headers

A list of headers set by authors for the request. Empty, unless explicitly set.

request entity body

The entity body for the request. Missing, unless explicitly set.

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.

referrer source

Either a Document or URL. Used to determine the Referer header.

manual redirect flag

Set when redirects are not to be automatically followed.

omit credentials flag

Set when user credentials are to be excluded in the request and when cookies are to be ignored in its response.

force preflight flag

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:

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

  2. If the following conditions are 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 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.)

7.1.1 Handling a Response to a Cross-Origin Request

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.

7.1.2 Cross-Origin Request Status

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:

preflight complete
The user agent is about to make the actual request.
success
The resource can be shared.
abort error
The user aborted the request.
network error
The resource cannot be shared. Also used when a DNS error, TLS negotiation failure, or other type of network error occurs. This does not include HTTP responses that indicate some type of error, such as HTTP status code 410.

7.1.3 Source Origin

The source origin is the initial origin that user agents must use for the Origin header. It can be modified during the redirect steps.

7.1.4 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 manual redirect flag is unset and the response has an HTTP status code of 301, 302, 303, 307, or 308

    Apply the redirect steps.

    If the end user cancels the request

    Apply the abort steps.

    If there is a 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.

    Otherwise

    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.

7.1.5 Cross-Origin Request with Preflight

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.

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

    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:

    The following request rules are to be observed while making the preflight request:

    If the end user cancels the request

    Apply the abort steps.

    If the response has an HTTP status code that is not in the 2xx range

    Apply the network error steps.

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

    If there is a 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.

    Otherwise (the HTTP status code is in the 2xx range)
    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. 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.

    5. Let headers be the empty list.

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

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

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

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

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

    11. 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.
      url
      The request URL.
      max-age
      The max-age.
      credentials
      False if the omit credentials flag is set, or true otherwise.
      method
      The given method.
      header
      Empty.
    12. 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.
      url
      The request URL.
      max-age
      The max-age.
      credentials
      False if the omit credentials flag is set, or true otherwise.
      method
      Empty.
      header
      The given header.
  2. Set the cross-origin request status to preflight complete.

  3. This is the actual request. Apply the make a request steps and observe the request rules below while making the request.

    If the response has an HTTP status code of 301, 302, 303, 307, or 308

    Apply the cache and network error steps.

    If the end user cancels the request

    Apply the abort steps.

    If there is a 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.

    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 set the cross-origin request status 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.

7.1.6 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.
url
Holds the request URL.
max-age
Holds the Access-Control-Max-Age header value.
credentials
False if the omit credentials flag is set, or true otherwise.
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.

Although this effectively makes the preflight result cache optional, user agents are strongly encouraged to support it.

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

  1. Let original URL be the request URL.

  2. Let request URL be the URL conveyed by the Location header in the redirect response.

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

  4. If the request URL contains the userinfo production apply the network error steps.

  5. If the resource sharing check for the current resource returns fail, apply the network error steps.

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

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

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

  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.

7.2 Resource Sharing Check

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

  1. If the response includes zero or more than one Access-Control-Allow-Origin header values, return fail and terminate this algorithm.

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

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

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

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

  6. Return pass.

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

7.3 Security

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

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.

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

8.1 Constructing a Cross-Origin Request

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.

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

8.3 Dealing with the Cross-Origin Request Status

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:

preflight complete

Features that can only be safely exposed after a preflight request can now be enabled.

E.g. upload progress events for XMLHttpRequest.

success

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.

abort error

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.

network error

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

8.4 Security

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.

References

[CONFUSED]
(Non-normative) The Confused Deputy, Norm Hardy.
[COOKIES]
HTTP State Management Mechanism, Adam Barth. IETF.
[CSRF]
(Non-normative) Cross-Site Request Forgeries, Peter Watkins.
[EVENTSOURCE]
(Non-normative) Server-Sent Events, Ian Hickson. W3C.
[HTML]
HTML5, Berjon, Leithead, Navara, O'Connor, Pfeiffer and Hickson. W3C.
[HTTP]
Hypertext Transfer Protocol -- HTTP/1.1, Roy Fielding, James Gettys, Jeffrey Mogul et al.. IETF.
[308]
The Hypertext Transfer Protocol (HTTP) Status Code 308 (Permanent Redirect), Julian Reschke. IETF.
[JSONP]
(Non-normative) JSONP, Bob Ippolito.
[OAUTH]
(Non-normative) The OAuth 1.0 Protocol, Eran Hammer-Lahav. IETF.
[ORIGIN]
The Web Origin Concept, Adam Barth. IETF.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, Scott Bradner. IETF.
[URI]
Uniform Resource Identifier (URI): Generic Syntax, Tim Berners-Lee, Roy Fielding and Larry Masinter. IETF.
[XHR]
(Non-normative) XMLHttpRequest, Anne van Kesteren. W3C.

Acknowledgments

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.