514

I have two questions. I understand that if I specify the domain as .mydomain.com (with the leading dot) in the cookie that all subdomains can share a cookie.

Can subdomain.mydomain.com access a cookie created in mydomain.com (without the www subdomain)?

Can mydomain.com (without the www subdomain) access the cookie if created in subdomain.mydomain.com?

adam0101
  • 23,476
  • 18
  • 75
  • 147
  • 3
    Yes you can.. please see link below http://www.codeguru.com/csharp/csharp/cs_internet/article.php/c19417/Sharing-Cookies-Across-Domains.htm – Rahul Jain Sep 23 '13 at 22:08
  • Closely related: http://stackoverflow.com/questions/3089199/can-subdomain-example-com-set-a-cookie-that-can-be-read-by-example-com – Ciro Santilli新疆棉花TRUMP BAN BAD Nov 10 '14 at 08:17
  • can you please look at this question http://stackoverflow.com/questions/38351769/path-attribute-of-cookie-is-not-affecting-for-subsequent-requests – Jayavardhan Gange Jul 14 '16 at 04:22
  • 1
    @adam0101 What if domain and sub domain are hosted on different server ? – user3782114 Dec 09 '16 at 15:48
  • 3
    @user3782114, it doesn't matter if they are on different servers. In my case, they were not only on different servers, but each domain was load-balanced across multiple servers. One thing that did trip us up a bit was that the lower environments (dev, test, uat, etc) started sharing the same cookie too once we did this because we had named them like "dev.oursite.com", "test.oursite.com", etc.. The trick there (at least in .Net) is to have a separate machine key generated for each environment and save that in your Web.config (assuming you transform the config for each environment). – adam0101 Dec 12 '16 at 02:19

7 Answers7

812

The 2 domains mydomain.com and subdomain.mydomain.com can only share cookies if the domain is explicitly named in the Set-Cookie header. Otherwise, the scope of the cookie is restricted to the request host. (This is referred to as a "host-only cookie". See What is a host only cookie?)

For instance, if you sent the following header from subdomain.mydomain.com, then the cookie won't be sent for requests to mydomain.com:

Set-Cookie: name=value

However if you use the following, it will be usable on both domains:

Set-Cookie: name=value; domain=mydomain.com

This cookie will be sent for any subdomain of mydomain.com, including nested subdomains like subsub.subdomain.mydomain.com.

In RFC 2109, a domain without a leading dot meant that it could not be used on subdomains, and only a leading dot (.mydomain.com) would allow it to be used across multiple subdomains (but not the top-level domain, so what you ask was not possible in the older spec).

However, all modern browsers respect the newer specification RFC 6265, and will ignore any leading dot, meaning you can use the cookie on subdomains as well as the top-level domain.

In summary, if you set a cookie like the second example above from mydomain.com, it would be accessible by subdomain.mydomain.com, and vice versa. This can also be used to allow sub1.mydomain.com and sub2.mydomain.com to share cookies.

See also:

cmbuckley
  • 33,879
  • 7
  • 69
  • 86
  • So I had two questions in my original post. Are you saying the answer is "yes" to both, but only on newer browsers? – adam0101 Apr 16 '14 at 15:04
  • If I set the cookie on both subdomain.mydomain.com and mydomain.com, do I have to set them as `Set-Cookie: name=value; domain=mydomain.com` on **both** domains to make them (the cookies) shared? – アレックス Dec 21 '14 at 13:13
  • 2
    I don't understand why you wouldn't just put the leading "." on the domain for maximum compatibility with old and new – Alan Macdonald Dec 21 '15 at 08:56
  • 19
    In the old standard, a cookie with `domain=.mydomain.com` is not valid for the bare mydomain.com, so the two RFCs are not compatible with each other. – cmbuckley Dec 21 '15 at 09:27
  • The final test links are not very good. The first does not seem to work at all, since the non-prefix version always redirects to www. The second works fine, but does not show multiple cookies. You can set multiple cookies with the same name (and different subdomains) and the browser sends them all, but the script only shows one. – BeniBela Jan 30 '17 at 00:57
  • I think the first link was working when this was posted :-) Regarding the second issue, that is by browser design; please see [How to handle multiple cookies with the same name?](http://stackoverflow.com/questions/4056306/how-to-handle-multiple-cookies-with-the-same-name]) – cmbuckley Jan 30 '17 at 10:38
  • @adam: technically www IS a subdomain, it's a special kind of subdomain, at least from the point of view of DNS servers. – Frank Feb 11 '18 at 19:22
  • 4
    @Frank, yes I know. My comment was to clarify that my question was regarding sharing cookies between a domain and a subdomain, NOT between two subdomains. – adam0101 Feb 12 '18 at 16:43
  • @AlanMacdonald because security as a default is better. also maybe you have an existing site you need to shunt to a subdomain and the original site didn't use `.` so all your users would get logged out under the old spec. – Simon_Weaver Jun 29 '18 at 23:01
  • I attempted to use this approach on a redirect but figured out I also needed to add a Path entry to the Set-Cookie header. My final header ended up looking like this: `"Set-Cookie", $"name=value; domain=mydomain.com; Path=/; Expires="` – laurencee Nov 28 '18 at 04:47
  • @laurencee as with `domain`, if `path` is not specified, it defaults to the scope of the request. The default value of the `path` attribute is the "parent directory" of the current path - so if the path is `/foo/bar`, the default path is `/foo`. A cookie (with no `path` attribute) set on the path `/foo/bar` would be sent for requests `/foo/baz`, but not for requests to `/`. Setting a `path` attribute allows you to override the scope of the cookie you set. [RFC 6265 § 5.1.4](https://tools.ietf.org/html/rfc6265#section-5.1.4) covers the matching logic. – cmbuckley Nov 28 '18 at 11:25
  • What if the cookie is created in sub1.mydomain.com, with the domain set to mydomain.com does sub2.mydomain.com then have access? – Shikyo Jun 12 '19 at 16:19
  • 1
    @shi Yes - please see the last sentence: "This can also be used to allow `sub1.mydomain.com` and `sub2.mydomain.com` to share cookies." – cmbuckley Jun 12 '19 at 17:47
  • @cmbuckley i thought so, i am hitting a wall here https://stackoverflow.com/questions/56560924/authentication-with-net-and-a-ssr-react-app – Shikyo Jun 13 '19 at 05:34
  • if no . some one could use afacebook.com and get all cookies as the . is not separating the wildcard – Walter Vehoeven Jan 25 '20 at 08:17
  • @WalterVehoeven that's not how the domain matching works - see [RFC 6265 § 5.1.3](https://tools.ietf.org/html/rfc6265#section-5.1.3). The string `afacebook.com` does not domain-match a domain string of `facebook.com` because the last character not included in the domain string is an `a`. – cmbuckley Jan 25 '20 at 15:39
  • 7
    I am not sure where to put this so I am choosing the comments of the accepted answer. It took long time and failed experiments to prove the above on my localhost, until it occurred to me that I should call the localhost with a dot in the name. Like "localhost.com" or something like that. Then all the "set cookies" behaviours started following the explanations written here in this answer. Hoping this might help somebody. – Cesc Mar 20 '20 at 16:31
  • Thank you. Saved my life LOL – Programadores Brasil Mar 13 '21 at 21:27
46

Please everyone note that you can set a cookie from a subdomain on a domain.

(sent in the response for requesting subdomain.mydomain.com)

Set-Cookie: name=value; Domain=mydomain.com // GOOD

But you CAN'T set a cookie from a domain on a subdomain.

(sent in the response for requesting mydomain.com)

Set-Cookie: name=value; Domain=subdomain.mydomain.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:

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

  2. 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.mydomain.com" domain-matches "mydomain.com", but "mydomain.com" does NOT domain-match "subdomain.mydomain.com"

Check this answer also.

Accountant م
  • 4,969
  • 2
  • 30
  • 49
  • 4
    This was the most helpful answer for me. – Toby Oct 22 '19 at 04:50
  • 1
    Thanks for providing a *documented* answer that gives the RFC refs explaining exactly when browsers are supposed to accept a cookie domain, and why it's okay for "foo.domain.com" to set a cookie for "domain.com", even though it seems it would violate the "same origin policy" and could be seen as a security risk. – odony Aug 12 '20 at 14:24
42

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

Velda
  • 527
  • 1
  • 5
  • 20
akostadinov
  • 15,093
  • 5
  • 64
  • 79
  • 4
    That looks to agree with what I'm saying: unless you specify a `domain`, the cookie is only used for the request host. This means that `Set-Cookie: name=value` from `mydomain.com` won't be sent with requests to subdomains. Have a play with [this test script](http://scripts.cmbuckley.co.uk/cookies.php) too. – cmbuckley Jul 21 '16 at 10:00
  • @cmbuckley, ok, what you said seems correct. I'll reword my answer. Thank you for pointing that out. – akostadinov Jul 21 '16 at 22:14
  • Need to point out, that section 4.1.2 (first citation) is not normative... – Velda Jul 26 '18 at 12:07
  • thanks for the cmbuckley link. nice to test how it works quickly. – lawphotog Jan 21 '19 at 14:50
25

Here is an example using the DOM cookie API (https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie), so we can see for ourselves the behavior.

If we execute the following JavaScript:

document.cookie = "key=value"

It appears to be the same as executing:

document.cookie = "key=value;domain=mydomain.com"

The cookie key becomes available (only) on the domain mydomain.com.


Now, if you execute the following JavaScript on mydomain.com:

document.cookie = "key=value;domain=.mydomain.com"

The cookie key becomes available to mydomain.com as well as subdomain.mydomain.com.


Finally, if you were to try and execute the following on subdomain.mydomain.com:

document.cookie = "key=value;domain=.mydomain.com"

Does the cookie key become available to subdomain.mydomain.com? I was a bit surprised that this is allowed; I had assumed it would be a security violation for a subdomain to be able to set a cookie on a parent domain.

lammy
  • 3,345
  • 1
  • 20
  • 21
  • 1
    This makes me wonder if there are separate specs describing the behavior of `httponly` cookies versus the kind of cookies you are creating. – adam0101 Sep 26 '17 at 21:37
  • 3
    The docs you posted do not agree with the statements you make. The first 2 examples are **not** equivalent (a `domain` attribute causes the cookie to work on subdomains; no such attribute does not). Leading dots are ignored at best and actively blocked at worst. – cmbuckley Jan 11 '18 at 20:44
  • this is the best solution if you don't want to rely on host headers. I checked it and its working – Szymon Aug 06 '19 at 09:47
4

Be careful if you are working on localhost ! If you store your cookie in js like this:

document.cookie = "key=value;domain=localhost"

It might not be accessible to your subdomain, like sub.localhost. In order to solve this issue you need to use Virtual Host. For exemple you can configure your virtual host with ServerName localhost.com then you will be able to store your cookie on your domain and subdomain like this:

document.cookie = "key=value;domain=localhost.com"
Alexandre97122
  • 311
  • 3
  • 14
3

In both cases yes it can, and this is the default behaviour for both IE and Edge.

The other answers add valuable insight but chiefly describe the behaviour in Chrome. it's important to note that the behaviour is completely different in IE. CMBuckley's very helpful test script demonstrates that in (say) Chrome, the cookies are not shared between root and subdomains when no domain is specified. However the same test in IE shows that they are shared. This IE case is closer to the take-home description in CMBuckley's www-or-not-www link. I know this to be the case because we have a system that used different servicestack cookies on both the root and subdomain. It all worked fine until someone accessed it in IE and the two systems fought over whose session cookie would win until we blew up the cache.

DannyW
  • 91
  • 3
-11

Simple solution

setcookie("NAME", "VALUE", time()+3600, '/', EXAMPLE.COM);

Setcookie's 5th parameter determines the (sub)domains that the cookie is available to. Setting it to (EXAMPLE.COM) makes it available to any subdomain (eg: SUBDOMAIN.EXAMPLE.COM )

Reference: http://php.net/manual/en/function.setcookie.php

Brett Wolfington
  • 6,191
  • 4
  • 29
  • 48
Lawes
  • 97
  • 3
  • 21
    This question is not PHP specific, I don't think it qualifies as valid. – sergelerator Aug 09 '16 at 21:53
  • 1
    Sergelerator, I did not pose a question. I was responding to the OP. – Lawes Sep 26 '17 at 21:01
  • 6
    @Lawes I believe sergelator means the OP's question is not PHP specific whereas your answer does seem to be a PHP-only solution, hence it wouldn't qualify to the OP's question. – Mirage Mar 15 '18 at 21:50