Zhong Yu, 2015-06-05
This article explains HTTP cookie domain policy, based on RFC_6265 and current browser behaviors.
A website can set a cookie in a response; the cookie will be sent back to the same website in subsequent requests.
More precisely, if an HTTP client issues a request to a domain, and the response contains a valid cookie, the client should apply the cookie to subsequent requests to the same domain (subject to other constraints). We say the request domain is the origin domain of the cookie. A cookie is always applicable to its origin domain.
For example, cookie
foo=bar originated from
www.cats.com is applied to later requests to the same domain -
request#0 GET http://www.cats.com:8080/abc HTTP/1.1 response#0 HTTP/1.1 200 OK Set-Cookie: foo=bar; Path=/; Expires=Sun, 02 Feb 2020 00:00:00 GMT ... request#n GET https://www.cats.com/xyz HTTP/1.1 Cookie: foo=bar
Note that the port number doesn't matter here; the scheme(
http/https) doesn't matter either (unless cookie's
Secure attribute is set). In the example above, the cookie originated from
http://www.cats.com:8080 is applicable to request to
https://www.cats.com:443 as well, even though the schemes and ports are different.
If the request host is an IP address, e.g.
127.0.0.1, we say, for the purpose of this article, that the origin domain is the IP.
A cookie can have the "Domain" attribute set to a valid domain name, which we call the cover domain of the cookie. If the "Domain" attribute is not set, we say the cover domain is null.
If cover domain is null, a cookie is only applicable to its origin domain. For example, a cookie from
www.cats.com is not applicable to
cats.com, and vice versa, if cover domain is null.
If cover domain is set, a cookie is applicable to the cover domain and all its subdomains. For example
request#0 GET http://foo.www.cats.com/ HTTP/1.1 response#0 HTTP/1.1 200 OK Set-Cookie: foo=bar; Path=/; Domain=cats.com
the cover domain is
cats.com, therefore the cookie is applicable to
The cover domain must cover the origin domain, that is, the cover domain must be the same as, or a parent of, the origin domain. In the example above, the origin domain is
foo.www.cats.com, therefore the cover domain could only be set to
cats.com (but not
"com", see next section).
If the origin domain is an IP, the cover domain must be null. A cookie with an IP origin is only applicable to that IP.
A cover domain should not contain a leading dot, like in
.cats.com; if it does, the client should remove the leading dot.
If a cookie's cover domain is set illegally or incorrectly, the client should ignore the cookie entirely.
On a related matter, a cookie's identity is defined by the triplet
(name, domain, path), of which
domain is either the cover domain if it's set, or the origin domain otherwise. This needs to be noted when replacing or deleting a cookie.
Obviously, we cannot allow a cover domain to be
"com", otherwise, a cookie from
cats.com could be sent to
dogs.com, causing problems. A cover domain must not be a public suffix.
A public suffix is a domain under which the general public can register direct subdomains. For example,
"co.uk" are public suffixes. Direct subdomains of a public suffix belong to different owners, therefore their cookies should not mingle, and that's why a public suffix cannot be allowed as cover domain.
A private company can also offer a domain as a public suffix. For example, when you lease a server from Amazon AWS, a domain name is assigned to it, e.g.
foo.compute.amazonaws.com. You "own" this domain in the sense that its usage is at your discretion. Someone else may own a sibling
bar.compute.amazonaws.com. To prevent
bar from sending cookies to
foo, the domain
compute.amazonaws.com is listed as a public suffix.
The complete list of public suffixes is maintained at https://publicsuffix.org. In addition, we recommend that
As far as cookie handling is concerned, every TLD is a public suffix, even if it's not listed. For example,
"my-fake-tld", etc. cannot be allowed as cover domains.
As far as cookie handling is concerned, parents of a public suffix are public suffixes too, even if they are not listed. For example,
amazonaws.com is not listed as a public suffix, yet it cannot be allowed as cover domain either, because it is the parent of public suffix
These two bullet points cannot be derived from the texts of RFC_6265 and publicsuffix.org; instead, they are concluded from current behaviors of major browsers. Other client and server implementers should follow these behaviors too. It's a simplified and conservative approach for dealing with subtleties of public suffix. See next section for a more complicated narrative.
Summary of rules from above:
According to RFC_6265, if a cookie's cover domain is a public suffix,
The first clause looks odd, but it permits a public suffix domain (if it ever resolves to an HTTP server) to specify itself as the cover domain, while making sure the cookie will not propagate to subdomains. Presumably, this clause is for backward compatibility of some existing websites on public suffix domains. However, the only major browser that currently implements this clause is Firefox; all other major browsers simply reject such cookies. Therefore in the previous section, to follow the browser consensus, we reject this case as well - a cover domain cannot be a public suffix, regardless of the origin domain.
Another problem - RFC_6265 does not properly handle the situation where a public suffix has a parent that is not a public suffix; such situation probably didn't exist when the RFC was written. Strictly following the texts of the RFC, a client would allow
foo.compute.amazonaws.com to set a cookie's cover domain to
amazonaws.com, and the cookie would be applicable to
bar.compute.amazonaws.com. This behavior is clearly undesired.
Fortunately, no major browser behaves that way; however, browsers handle the case differently. Safari appears to simply treat
amazonaws.com as a public suffix, rejecting all cookies with it as cover domain. In the previous section, we follow this simple approach, rejecting any parent of public suffix as cover domain.
On the other hand, Firefox and Chrome take a more sophisticated approach, allowing
amazonaws.com as cover domain in some cases (e.g. when the origin domain is
www.amazonaws.com) while making sure those cookies do not propagate below
compute.amazonaws.com. This approach is better; however, Amazon cannot really rely on it to share cookies, because not all browsers support the approach.
These discussions intend to justify the conservative approach we laid out in the previous section.
Nevertheless, it would be interesting to discuss what is the "ideal" way to handle public suffixes in cookie handling -
amazonaws.com is not really a public suffix, because its direct subdomains are not open to the public; instead, they are all controlled by Amazon. It doesn't really hurt if
zzz.amazonaws.com, or even
compute.amazonaws.com, share cookies though domain
amazonaws.com - as long as these cookies do not propagate downwards across public suffix
compute.amazonaws.com, reaching user websites. At the same time, we must not allow a user website under
compute.amazonaws.com to set a cover domain to
amazonaws.com, interfering with Amazon's websites.
With that in mind, the next section defines a more sensible model for cookie domain policy.
A cover domain's coverage is the set of domains that the cookie is applicable to; the set is defined by:
That is, the coverage starts from the domain, propagates downwards, stopped at public suffix nodes.
The coverage is tested when receiving and sending the cookie, in a symmetric way
Return to the Amazon example,
compute.amazonaws.comonly covers itself, since it's a public suffix.
compute.amazonaws.com; it does not cover
Here's a pseudo code for getting the
list of cover domains that cover a given
list.add(request_domain) for each parent of request_domain, ordered from longest to shortest if parent is a public suffix break loop list.add(parent)