Share cookie between subdomain and domain
I'm not sure @cmbuckley answer is showing the full picture. What I read is:
Unless the cookie's attributes indicate otherwise, the cookie is returned only to the origin server (and not, for example, to any subdomains), and it expires at the end of the current session (as defined by the user agent). User agents ignore unrecognized cookie.
RFC 6265
Also
8.6. Weak Integrity
Cookies do not provide integrity guarantees for sibling domains (and
their subdomains). For example, consider foo.example.com and
bar.example.com. The foo.example.com server can set a cookie with a
Domain attribute of "example.com" (possibly overwriting an existing
"example.com" cookie set by bar.example.com), and the user agent will
include that cookie in HTTP requests to bar.example.com. In the
worst case, bar.example.com will be unable to distinguish this cookie
from a cookie it set itself. The foo.example.com server might be
able to leverage this ability to mount an attack against
bar.example.com.
To me that means you can protect cookies from being read by subdomain/domain but cannot prevent writing cookies to the other domains. So somebody may rewrite your site cookies by controlling another subdomain visited by the same browser. Which might not be a big concern.
Awesome cookies test site provided by @cmbuckley /for those that missed it in his answer like me; worth scrolling up and upvoting/:
- http://scripts.cmbuckley.co.uk/cookies.php
If you set a cookie like this:
Set-Cookie: name=value
then the cookie will only apply to the request domain, and will only be sent for requests to the exact same domain, not any other subdomains. (See What is a host only cookie?)
Two different domains (e.g. example.com
and subdomain.example.com
, or sub1.example.com
and sub2.example.com
) can only share cookies if the domain
attribute is present in the header:
Set-Cookie: name=value; domain=example.com
The domain attribute must "domain-match" the request URL for it to be valid, which basically means it must be the request domain or a super-domain. So this applies for both examples in the question, as well as sharing between two separate subdomains.
This cookie would then be sent for any subdomain of example.com
, including nested subdomains like subsub.subdomain.example.com
. (Bear in mind there are other attributes that could restrict the scope of the cookie and when it gets sent by the browser, like path
or Secure
).
Because of the way the domain-matching works, if you want sub1.example.com
and sub2.example.com
to share cookies, then you'll also share them with sub3.example.com
.
See also:
- www vs no-www and cookies
- cookies test script to try it out
A note on leading dots in domain
attributes: In the early RFC 2109, only domains with a leading dot (domain=.example.com
) could be used across subdomains. But this could not be shared with the top-level domain, so what you ask was not possible in the older spec.
However, the newer specification RFC 6265 ignores any leading dot, meaning you can use the cookie on subdomains as well as the top-level domain.
Please everyone note that you can set a cookie from a subdomain on a domain.
(sent in the response for requesting subdomain.example.com
)
Set-Cookie: name=value; Domain=example.com // GOOD
But you CAN'T set a cookie from a domain on a subdomain.
(sent in the response for requesting example.com
)
Set-Cookie: name=value; Domain=subdomain.example.com // Browser rejects cookie
WHY?
According to the specifications RFC 6265 section 5.3.6 Storage Model
If the canonicalized request-host does not domain-match the domain-attribute: Ignore the cookie entirely and abort these steps.
and RFC 6265 section 5.1.3 Domain Matching
Domain Matching
A string domain-matches a given domain string if at least one of the following conditions hold:
The domain string and the string are identical. (Note that both the domain string and the string will have been canonicalized to lower case at this point.)
All of the following conditions hold:
* The domain string is a suffix of the string. * The last character of the string that is not included in the domain string is a %x2E (".") character. * The string is a host name (i.e., not an IP address).
So subdomain.example.com
domain-matches example.com
, but example.com
does NOT domain-match subdomain.example.com
Check this answer also.