Access Control for Cross-site Requests

W3C

Access Control for Cross-site Requests

W3C Working Draft 26 November 2007

This Version:
http://www.w3.org/TR/2007/WD-access-control-20071126/
Latest Version:
http://www.w3.org/TR/access-control/
Previous Versions:
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-site requests. It defines a request algorithm for GET and non-GET requests that specifications that want to enable cross-site requests in the technologies they define can use.

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 26 November 2007 Working Draft of the "Access Control for Cross-site Requests" document. This draft has been renamed from "Enabling Read Access for Web Resources" to better and more clearly reflect what it defines. It is expected that this document will progress along the W3C Recommendation track. This document is produced by the Web Application Formats (WAF) Working Group. The WAF Working Group is part of the Rich Web Clients Activity in the W3C Interaction Domain.

Please send comments to the WAF Working Group's public mailing list public-appformats@w3.org with [access-control] 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

Cross-site requests are possible using the HTML img and script elements for instance. However, it is not possible to exchange the contents of resources or manipulate resources "cross-domain". This is to prevent information leakage and to ensure that malicious site can not delete your calendar data with cross-site requests using the HTTP DELETE method.

The policy this document introduces allows a resource to opt-in to allowing cross-site data retrieval of it and also enables a mechanism based on the same policy to allow a resource to opt-in to requests using an HTTP method other than GET. This policy builds on top of the existing restrictions already in place. This policy described in this document can only be used by a technology, such as XMLHttpRequest or XBL, when the respective specification of that technology describes how it applies.

The access control policy is defined in the resource that might be obtained and is expected to be enforced by the client that retrieves and processes the resource. Thus the client is trusted and acts as a policy enforcement point.

If you have a simple text resource residing at http://example.com/hello which contains the string "Hello World!" and you would like the hello-world.invalid domain to be able to access it the resource would look as follows (including one HTTP header that is significant):

Access-Control: allow <hello-world.invalid>

Hello World!

The hello-world.invalid can now access this document using XMLHttpRequest for instance with the following code:

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

It gets slightly more complicated if you want your resource to be able to handle cross-site requests using the HTTP DELETE and POST methods. Your resource first needs to reply to an authorization request that uses the GET method and has the Method-Check HTTP header set and then needs to handle the request that uses the POST or DELETE method and give an appropriate response. The reply to the authorization request can have the following HTTP headers specified for instance:

Access-Control: allow <hello-world.invalid> method DELETE, POST
Method-Check-Expires: Sun, 06 Nov 2012 08:49:37 GMT

The Method-Check-Expires indicates how long the response can be cached so that for subsequent requests involving the HTTP DELETE and POST methods no authorization request has to be made. The response to the actual request can simply contain this header:

Access-Control: allow <hello-world.invalid>

As opposed to handling such a request, actually making a request like that is not difficult as the complexity of doing the additional authorization request is the task of the user agent. Using XMLHttpRequest again and assuming the application were hosted at http://calendar.invalid/app you could do something like the following:

function deleteItem(itemId, updateUI) {
  var client = new XMLHttpRequest()
  client.open("DELETE", "http://calendar.invalid/app")
  client.onload = updateUI
  client.onerror = updateUI
  client.onabort = updateUI
  client.send("id=" + itemId)
}

XMLHttpRequest Level 2 includes support for cross-site access requests though it has not yet been published as a W3C Working Draft.

It is also possible to specify which domains are allowed to access your resource using XML:

<?access-control allow="http://hello-world.invalid https://test.example.net"?>
<hello type="world"/>

You can even combine these two techniques:

Access-Control: allow <http://hello-world.invalid>

<?access-control allow="https://test.example.net"?>
<hello type="world"/>

2. Conformance Criteria

This specification is applicable to both user agents and other specifications. This specification will only apply in certain contexts and specifications defining such contexts will define when and how this specification applies.

As well as sections 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, must not, should, should not and may are to be interpreted as described in RFC 2119. [RFC2119]

A conformant specification is one that implements all the requirements listed in this specification that are applicable to specifications. For instance, a specification needs to define what the source for the referrer root URI is.

A conformant user agent is one that implements all the requirements listed in this specification that are applicable to user agents, while also being consistent with the requirements listed in the specifications that use the access control read policy.

User agents may optimize any algorithm given in this specification, so long as the end result is indistinguishable from the result that would be obtained by the specification's algorithms. (The algorithms in this specification are generally written with more concern for clarity than efficiency.)

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.

The term ToASCII algorithm means that the ToASCII algorithm as described in RFC 3490 is applied with both the AllowUnassigned and UseSTD3ASCIIRules flags set. [RFC3490]

There is a case-insensitive match of strings s1 and s2 if after mapping the ASCII character range A-Z to the range a-z both strings are identical.

U+0009, U+000A, U+000D and U+0020 are space characters.

A space-separated list is a string of which the items are separated by one or more space characters (in any order). The string may also be prefixed or suffixed with zero or more space characters.

To obtain the list of values from a space-separated list user agents must take the string, replace any sequence of space characters with a single U+0020 character, then drop any leading or trailing U+0020 character, then chop the resulting string at each occurrence of a U+0020 character, then drop all U+0020 values, and then return the list of values.

An XML MIME type is text/xml, application/xml or any MIME type ending in +xml.

Two URIs are same-origin if after performing scheme-based normalization on both URIs as described in section 5.3.3 of RFC 3987 the scheme, ihost and port components are identical. If either URI does not not have an ihost component the URIs must not be considered same-origin. [RFC3987]

3. Security Considerations

The access control mechanism defined in this specification allows for extension of the same-origin policy in contexts where the same-origin policy currently applies.

When making a cross-site access request user agents should ensure to:

User agents which implement this specification must also take care to properly normalize Unicode and to properly interpret IDNs to prevent URI spoofing attacks as outlined in the specification. [RFC3490]

Application authors should be aware that content retrieved from another site is not itself trustable. Authors should protect themselves against cross-site scripting attacks by not rendering or executing the retrieved content directly without validating that content.

Authors sharing content with domains that are on shared hosting environments should ensure to not allow access from arbitrary ports on those domains.

example.com could host some user-sensitive data protected by HTTP authentication or cookies. It has an agreement with company.invalid to share this data and therefore uses the following HTTP header:

Access-Control: allow <company.invalid:*>

Now company.invalid happens to be on a shared hosting environment with evil.example.net (they share the IP address). Because of this evil.example.net can host content at company.invalid:9999 and access user-sensitive data at example.com if the user, by phishing for instance, goes to company.invalid:9999. This can be prevented by clearly specifying the port or omitting it entirely letting it default to the default port of the URI scheme:

Authors should ensure that GET requests on their application has no side effects. If by some means an evil application finds out what applications a user is associated with it might "attack" these applications with GET requests that can effect the user's data if the user is already authenticated with any of these applications by means of cookies or HTTP authentication.

Integrity protection of the access control policy statements may be required. This could be achieved by use of SSL/TLS for example.

4. Syntax

EBNF should maybe be converted to ABNF. If someone can provide the editor some guidance on IRC or through e-mail that would be much appreciated.

4.1. Access Item

An access item is either a single * character (always matches) or a domain that can contain a wildcard at the start and can optionally have a scheme and port specified. An access item must match the following EBNF:

access-item    ::= (scheme "://")? domain-pattern (":" port-pattern)? | "*"
domain-pattern ::= domain | "*." domain
port-pattern   ::= port | "*"

scheme and port are used as defined in RFC 3986. domain is an internationalized domain name as defined in RFC 3490. [RFC3986] [RFC3490]

In addition to matching the above EBNF the ToASCII algorithm must apply successfully (without errors) to each label component of the subdomain (if any) from the access item.

Since HTTP syntax does not allow Unicode domain has to be written within the ASCII range resorting to the punycode syntax when necessary.

If the scheme omitted it will match any scheme from the referrer root URI. If port-pattern is omitted the port for the access item will be the default port for the scheme of the access item, or the default port of the scheme of the referrer root URI if the access item did not include a scheme. If port-pattern is * it will match any port.

When * is used as part of domain-pattern it matches any number of internationalized labels before domain. If just domain is used it will match itself and any number of internationalized labels before domain.

Several examples of conforming access items:

The following access items would make the user agent deny access to the resource:

The following access items are identical:

The following access items would match http://foo.bar.example.org:80:

4.2. Access-Control HTTP Response Header

Retrieved resources can have one or more Access-Control headers defined. These headers must match the following EBNF:

Access-Control ::= "Access-Control" ":" 1#rule
rule           ::= rule-allow | rule-deny
rule-allow     ::= "allow" (LWS pattern)+ exclude? (LWS "method" LWS #Method)?
rule-deny      ::= "deny" (LWS pattern)+ exclude?
exclude        ::= LWS "exclude" (LWS pattern)+
pattern        ::= "<" access item ">"

As stated by RFC 2616, multiple Access-Control headers can be combined.

The syntax of access items when used in the Access-Control HTTP header is restricted to internationalized domain names to which the ToASCII algorithm has been applied as HTTP does not support Unicode.

LWS and Method are used as defined by RFC 2616. The pattern production above must not include implied LWS. Implied LWS is allowed everywhere else. [RFC2616]

In case resources on a domain are not all in the control of a single person "deny" rules can be used by authors to deny read access from external resources to the entire domain. Read access from other domains is by default disallowed but individual resources on the domain could have <?access-control?> processing instructions specified which can allow access from other domains. Although files can contain processing instructions, HTTP headers can be set across an entire server making them far more effective. The "exclude" clause can be used to list exclusions to these "deny" rules.

"allow" rules can be used to allow read access from particular domains as long as those domains don't match any of the patterns listed in "exclude".

For cross-site non-GET access requests the server to which the request is made can list which non-GET methods are allowed using a comma-separated list after the "method" rule.

Access-Control: allow <*.example.org> exclude <*.public.example.org>
Access-Control: allow <webmaster.public.example.org>

Means that every subdomain of example.org can access the resource including webmaster.public.example.org, but with the exclusion of all other subdomains of public.example.org.

Access-Control: allow <example.org>

Means that example.org and all its subdomains can access the resource.

Access-Control: allow <example.org> <example.invalid> method POST, PUT

Means that example.org and example.invalid can access the resource and perform POST and PUT requests.

4.3. <?access-control?> Processing Instruction

XML resources may include an <?access-control?> processing instruction within the XML Prolog to indicate, if the access control read policy applies, from which domains their content can be accessed. [XML]

The processing instruction takes three pseudo-attributes which each take a space-separated list of access items and one psuedo-attribute which takes a space-separated list of HTTP methods. These pseudo-attributes are allow, deny, exclude, and method. Either the allow or deny pseudo-attribute must be specified. allow and deny must not be specified at the same time. If an attribute is specified it must at least contain an access item. If the deny psuedo-attribute is specified the method attribute must not be specified.

An <?access-control?> processing instruction that is part of the XML Prolog must be parsed using the same syntax rules as described in the XML Stylesheet PI specification. <?access-control?> processing instructions outside the XML Prolog are ignored. [XMLSSPI]

The above means that the following examples would be non-conforming and would make the user agent deny access to the resource:

4.4. Referer-Root (sic) HTTP Request Header

The Referer-Root (sic) request HTTP header helps servers knowing where the request originates in case the Referer header is not included in the request. It also indicates that the request is a cross-site access request. The header must match the following EBNF:

Referer-Root ::= "Referer-Root" ":" referrer root URI

4.5. Method-Check HTTP Request Header

The Method-Check request HTTP header informs the server that the client is making an authorization request and will make a subsequent request to the same URI using a different method specified in the Method-Check HTTP header if that is allowed by the server per the semantics of authorization requests. The Method-Check HTTP header must match the following EBNF:

Method-Check ::= "Method-Check" ":" Method

The Method production is defined in RFC 2616. [RFC2616]

4.6. Method-Check-Expires HTTP Response Header

The Method-Check-Expires HTTP response header indicates how long the results of an authorization request can be cached in an authorization request cache. The Method-Check-Expires HTTP header must match the following EBNF:

Method-Check-Expires ::= "Method-Check-Expires" ":" HTTP-date

The HTTP-date production is defined in RFC 2616. [RFC2616]

5. Processing Model

The various subsections below describe the various processing models user agents and specifications have to implement.

5.1. Cross-site Access Request

A cross-site access request takes the parameters request URI and request method. If request method is equal to GET the user agent must follow the cross-site GET access request algorithm. Otherwise the cross-site non-GET access request algorithm.

These algorithms have shared return values that specifications can use to instruct user agents what to do. The status return flag indicates the status of the cross-site access request. It takes the value "success" when cross-site access to the resource is allowed, "same-origin" if the cross-site request turned into a same-origin request due to redirects, "network" if a network error of some sort occurred, and "abort" if the user aborted the request. The uri return flag is used when the status return flag is "same-origin" to indicate the URI which the specification can use for a subsequent same-origin request.

As this algorithm is used by other specifications, those specifications must handle all values of the status return flag and handle the uri return flag.

The referrer root URI is the scheme followed by ://, followed by the domain without any trailing U+002E (.) (if any), followed by :, followed by the port (even if it is the default port for the scheme) of the source of the request. If the resource does not have a host-based authority (data: URI scheme for instance) the referrer root URI is "null".

Specifications using cross-site access requests must define the source of the request for the referrer root URI. Due to the way the origin for protocols is retrieved in different ways it is not possible to define this in a generic way.

While following the requirements for cross-site access requests user agents must ensure that each request has a Referer-Root HTTP request header set, with the value set to referrer root URI. This includes requests as a result of a redirect.

5.1.1. Generic Cross-site Access Request Algorithms

The variables used in the generic set of steps are part of the algorithms that invoke these set of steps.

The generic redirect steps are as follows:

If the new URI scheme is not supported, infinite loop precautions are violated, or something else went wrong terminate the algorithm that invoked this set of steps and return with the status flag set to "network".

Otherwise, let current request URI be the new URI and then follow these set of steps:

  1. If the current request URI and origin are same-origin terminate the algorithm that invoked this set of steps and return with the uri flag set to the current request URI and the status flag to "same-origin".
  2. Otherwise, transparently follow the redirect while observing the set of request rules.

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

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

Remove the cache entry means removing the entry in the authorization request cache which has as key the tuple (origin, current request URI).

5.1.2. Cross-site GET Access Request

The steps below describe what user agents must do for cross-site GET access requests. These are requests using the HTTP GET method to a non same-origin URI, the request URI.

  1. Let origin be the referrer root URI.

  2. Let current request URI be the request URI.

    The current request URI can be modified when applying the generic redirect steps.

  3. Then make a request to current request URI using the HTTP method GET and observe the following request rules:

    If the response is an HTTP redirect

    Apply the generic redirect steps.

    If the user cancels the request

    Apply the generic abort steps.

    If there is a network error

    Apply the generic network error steps.

    Otherwise

    Perform an access control check using GET as method. If it returns "fail" terminate this algorithm and return with the status flag set to "network". Otherwise, if it returns "pass", terminate this algorithm and return with the status flag set to "success". Do not actually terminate the request.

5.1.3. Cross-site Non-GET Access Request

Cross-site non-GET access requests use an authorization request cache that consists of a set of entries. Each entry has a key, list of methods, and an expiry date. Entries must be removed when the current time exceeds the time specified by the expiry date field. Besides expiring entries are 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.

The steps below describe what user agents must do for cross-site non-GET access requests. These are requests to a non same origin URI with an HTTP request method other than GET that first need to be authorized using either an authorization request cache entry or an authorization request.

  1. Let origin be the referrer root URI.

  2. Let request method be the request method parameter passed to the cross-site access request algorithm.

  3. Let current request URI be the request URI.

    The current request URI can be modified when applying the generic redirect steps.

  4. If there is an entry in the authorization request cache where the key matches the (origin, current request URI) tuple and the request method is in the list of methods proceed to the next step.

    Otherwise, remove the cache entry, if any, and then make an authorization request, by following this set of steps:

    1. Set the Method-Check HTTP request header to request method and then make a request using the HTTP GET method to the current request URI. The Method-Check HTTP request header is to persist during redirects. Ensure that the response to this request is not cached by specifying the appropriate HTTP headers, such as Cache-Control: no-cache.

    2. Observe the following request rules while making the request:

      If the response is an HTTP redirect

      Apply the generic redirect steps.

      If the user cancels the download

      Apply the generic abort steps.

      If there is a network error

      Apply the generic network error steps.

      Otherwise

      Perform an access control check using the request method as method . If it returns "fail" terminate this algorithm and return with the status flag set to "network". Otherwise, if it returns "pass" and a "method list", add an entry to the authorization request cache with as key the tuple (origin, current request URI), as list of methods the "method list" return value, and as expiry date the value of the Method-Check-Expires HTTP response header, if any. If there is no Method-Check-Expires HTTP response header the user agent may chose to nevertheless cache the entry for a short period of time or not store a cache entry at all. If there is a Method-Check-Expires HTTP response headers that can be successfully parsed and the current time exceeds the time specified by the header remove the cache entry.

  5. Make a request to the current request URI using HTTP method request method and observe the request rules below while making the request. For this request the Method-Check header is no longer set. The Referer-Root header is still set, obviously.

    If the response is an HTTP redirect

    First remove the cache entry and then apply the generic network error steps.

    If the user cancels the download

    Apply the generic abort steps.

    If there is a network error

    Apply the generic network error steps.

    Otherwise

    Perform an access control check using the request method as method. If it returns "fail" remove the cache entry, then terminate this algorithm, and return with the status flag set to "network". Otherwise, if it returns "pass", terminate this algorithm and return with the status flag set to "success". Do not actually terminate the request.

5.2. Access Control Check

5.2.1. Shared Algorithms

The algorithms in this section are to be read as if they were part of the algorithm that invoked them. The "overall set of steps" and "overall algorithm" are references to the algorithm that invoked algorithms defined in this section.

The deny list check algorithm takes a list of items consisting of match and exclude lists. For each item in the list run the following steps:

  1. If there is no match for any access item from the match list against the referrer root URI process the next list item. If there is no next list item go to the next step in the overall set of steps.

  2. If the exclude list is non-empty and there is a match for any access item from the exclude list against the referrer root URI process the next list item. If there is no next list item go to the next step in the overall set of steps.

  3. Terminate the overall algorithm and return "fail".

The allow list check algorithm takes a list of items consisting of match, exclude, and method lists. For each item in the list run the following steps:

  1. If there is no match for any access item from the match list against the referrer root URI process the next list item. If there is no next list item go to the next step in the overall set of steps.

  2. If the exclude list is non-empty and there is a match for any access item from the exclude list against the referrer root URI process the next list item. If there is no next list item go to the next step in the overall set of steps.

  3. If the request method is not GET and the request method is not in the method list process the next list item. If there is no next list item go to the next step in the overall set of steps.

    HTTP method comparison is case-sensitive.

  4. If the request method is not GET append the items from method list to temp method list.

  5. Set the allow access flag to "true".

  6. If the request method is GET go to the next step in the overall set of steps.

  7. Process the next list item. If there is no next list item go to the next step in the overall set of steps.

    This step ensures that temp method list gets all the necessary headers.

5.2.2. Access Control Check Algorithm

When a user agents has to make an access control check for a particular resource it must then associate the following with that resource:

The match lists and exclude lists are unordered lists of access items. The match lists are guaranteed to be non-empty and the exclude lists can be empty. The method lists are unordered lists of HTTP methods. They can be empty and are only used in an access control check as the result of an authorization request.

If an HTTP method name was passed as parameter to the access control check algorithm that will be the request method. If none was passed request method is GET. In addition there is the temp method list that will eventually be used for the authorization request cache entry.

After associating the aforementioned lists and when all HTTP headers have been received the user agent must run the following algorithm (unless stated otherwise):

  1. Parse the Access-Control headers. If any value does not conform to the syntax required terminate the algorithm and return "fail". Otherwise, if parsed successfully, then for each rule run the following steps:

    1. If rule is rule-allow append a new list item to the HTTP access control allow list where the match list is constructed of each access item following "allow", the exclude list of each access item following "exclude", and the method list of each HTTP method following "method". If "exclude" or "method" is not present their respective list will be empty.

    2. If rule is rule-deny append a new list item to the HTTP access control deny list where the match list is constructed of each access item following "deny" and the exclude list of each access item following "exclude". If "exclude" is not present the exclude list will be empty.

  2. Then run the deny list check on the HTTP access control deny list.

  3. Then run the allow list check on the HTTP access control allow list.

  4. If the requested resource has an XML MIME type go to the next step. Otherwise, if the allow access flag is "false" then terminate the algorithm and return "fail". If the allow access flag is "true" then terminate the algorithm, return "pass", and return the temp method list.

  5. Parse the resource as an XML document using a streaming XML parser following the rules set forth in the XML specification up to but not including the root element start tag. Then process the encountered <?access-control?> processing instructions (if any). [XML]

    If there is either an XML parse error or failure to parse the processing instructions terminate the overall algorithm and return "fail". Otherwise, run the following steps for each <?access-control?> processing instruction:

    1. If the processing instruction does not meet the following conditions then terminate the overall algorithm and return "fail":

      • No other pseudo-attributes than deny, allow, exclude, and method.
      • Either a deny or allow pseudo-attribute, but not both.
      • Optionally a method pseudo-attribute if there is an allow pseudo-attribute present.
    2. Let temp match list be the result of parsing the allow or deny pseudo-attribute value, whichever is present. If any obtained value does not match the access item syntax or if no values was obtained terminate the overall algorithm and return "fail".

    3. If there is an exclude pseudo-attribute let temp exclude list be the result of parsing the exclude pseudo-attribute value. If any obtained value does not match the access item syntax or if no value was obtained terminate the overall algorithm and return "fail". If there is no such pseudo-attribute let temp exclude list be empty.

    4. If there is an allow pseudo-attribute append a new list item to the PI access control allow list where the match list is temp match list, the exclude list is temp exclude list, and the method list is the result of parsing the method pseudo-attribute or the empty list if the attribute is not present.

      Otherwise, there is a deny psuedo-attribute. Append a new list item to the PI access control deny list where the match list is temp match list and the exclude list is temp exclude list.

  6. Then run the deny list check on the PI access control deny list.

  7. Then run the allow list check on the PI access control allow list.

  8. If the allow access flag is "false" then return "fail". Otherwise, if the allow access flag is "true", then return "pass" and return the temp method list.

5.3. Access Item Check

To determine whether a referrer root URI and an access item match user agents must run the following algorithm:

  1. Let origin be referrer root URI and item be access item.

  2. If item is a single U+002A (*) there is a match. Terminate this algorithm.

  3. If origin is "null" there is no match. Terminate this algorithm.

  4. If item does not have a port-pattern let the port of item be the default port for the scheme of item or, if item does not have a scheme, let it be the default port of the scheme of origin.

  5. If item has a scheme and it does not case-insensitively match the scheme from origin there is no match. Terminate this algorithm.

  6. Remove the scheme from item (if it has one specified) and origin including the :// sequence following it.

  7. If the port from item does not match the port from origin and is not * there is no match. Terminate this algorithm.

  8. Remove the port from item and origin including the U+003A (:) preceding it.

  9. If item item has a single U+002E (.) as last character remove that character from item.

  10. Let origin list be origin split on the U+002E (.) character (dropping that character in the process) and item list be item split on the U+002E (.) character (dropping that character in the process). Ensure that the order is preserved.

  11. Reverse the order of origin list and item list.

  12. Now process the first list item of both origin list and item list using the following steps:

    1. Let the item from origin list be origin label and the item from item list be item label.

    2. If item label is a single U+002A (*) character move to the next step in the overall set of steps.

    3. Apply the ToASCII algorithm to origin label and item label and store the result in those variables respectively.

    4. If origin label does not case-insensitively match item label there is no match (terminate the overall algorithm).

      Otherwise, apply these set of steps to the next list item of both origin list and item list. If the origin list has no next list item there is no match (terminate the overall algorithm.) If the item list has no next list item go to the next step in the overall set of steps.

  13. There is a match. Terminate this algorithm.

References

[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
[RFC3490]
Internationalizing Domain Names in Applications (IDNA), P. Faltstrom, P. Hoffman, A. Costello. IETF, March 2003.
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax, T. Berners-Lee, R. Fielding, L. Masinter, editors. IETF, January 2005.
[XML]
Extensible Markup Language (XML) 1.0 (Fourth Edition), T. Bray et al., editors. W3C, August 2006.
Namespaces in XML 1.0 (Second Edition), T. Bray et al., editors. W3C, August 2006.
[XMLSSPI]
Associating Style Sheets with XML documents, J. Clark, editor. W3C, June 1999

Acknowledgments

The editor would like to thank Arthur Barstow, Benjamin Hawkes-Lewis, Cameron McCormack, David Håsäther, 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, Mohamed Zergaoui, Sharath Udupa, Sunava Dutta, Thomas Roessler, and Zhenbin Xu for their contributions to this specification.

Special thanks to Brad Porter, Matt Oshry and R. Auburn who helped editing earlier versions of this document.