704

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

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

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
adam0101
  • 29,096
  • 21
  • 96
  • 174
  • 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
  • 1
    Closely related: http://stackoverflow.com/questions/3089199/can-subdomain-example-com-set-a-cookie-that-can-be-read-by-example-com – Ciro Santilli OurBigBook.com Nov 10 '14 at 08:17
  • 2
    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
  • 11
    @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

1075

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 "parent" 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 example.com and 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:


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.

cmbuckley
  • 40,217
  • 9
  • 77
  • 91
  • 1
    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? – Incerteza Dec 21 '14 at 13:13
  • 3
    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
  • 47
    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
  • 6
    @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
  • 4
    @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 Verhoeven 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
  • 14
    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
  • Will it work also if I need to make a request from x.mydomain.com to y.mydomain.com with the x.mydomain.com cookies? – roadev Jun 09 '21 at 04:23
  • @roadev yes - read the final paragraph of the post about `sub1` and `sub2` being able to share cookies. – cmbuckley Jun 09 '21 at 12:04
  • Regardless of what everybody says, I feel the need to point out that using .example.com is a security misconfiguration, especially if your main domain contains a lot of different subdomains. Using this with a session cookie would mean sending that cookie to every subdomain the user visits, which may be leveraged by an attacker that manages to control a server with such a subdomain. – Dani Cuesta Dec 01 '21 at 07:22
  • 2
    It is not a good idea to refer to this as a "security misconfiguration." Cookies, particularly those containing sensitive data, should ideally be scoped to tightest domain/path restrictions that are appropriate. Scoping across the entire domain may be a bad idea especially for a sprawling estate, but it may also be necessary. It is important to highlight the risks, and might be a good idea to re-architect to prevent any issues, but is not fair to call this a misconfiguration. – cmbuckley Dec 02 '21 at 14:56
  • 1
    I honestly had to read the next answer down to understand what this answer is trying to say. I have no issue with bad english, but this is vague implicitive logic, with a smattering of links – Jay Day Zee Mar 24 '22 at 07:41
  • @cmbuckley if I have the leading dot, in old RFC, the cookies would only be shared between subdomains but not to the domain, but in new RFC, the cookies would be shared to the domain as well. And if I don't have the leading dot, the cookies would be shared with both domain and subdomains in both RFCs. **Is this correct?** – ADTC Feb 08 '23 at 10:56
  • @ADTC your second statement is not correct - if you don't have the leading dot, the cookie does not apply to subdomains in the old RFC. But per the note at the end, there are very few cases where the leading dot isn't ignored - probably only if you have to care about IE8/9, for instance. – cmbuckley Feb 08 '23 at 15:36
  • _"if you don't have the leading dot, the cookie does not apply to subdomains in the old RFC."_ and _"there are very few cases where the leading dot isn't ignored - probably only if you have to care about IE8/9"_ Please add these in your answer, in _"A note on leading dots"_. That ought to clear up everyone's confusion. In a gist, in the old RFC, leading dot = subdomains only (no domain), no leading dot = domain only (no subdomains), and in new RFC, it doesn't matter if there's a leading dot or no leading dot, it's _**always**_ both domain and subdomains. – ADTC Feb 08 '23 at 16:04
  • @ADTC the first statement is already in the answer, and whilst a comment [here](https://stackoverflow.com/a/20884869/283078) led me to believe IE8/9 might behave differently, subsequent testing suggests that might not be true. – cmbuckley Feb 08 '23 at 17:06
  • How can i set the cookie, only for a specific sub domain, I dont want all subdomains to access it ??? – Yuvraj Agarkar Jun 26 '23 at 15:07
  • @YuvrajAgarkar the only way to do this would be to set a cookie from the subdomain. For example if you set a cookie on https://a.setcookie.net/, you can restrict it to that subdomain (either choose a.setcookie.net or unspecified as the domain). – cmbuckley Jun 26 '23 at 19:03
  • @cmbuckley, it works on the a.setcookie.net tool but not on my hosted project i get warning in frontend and the cookie does not get attached ` attempt to set cookie was blocked because it's domain attribute was invalid with regards to host url` but i'm pretty sure i have put the right url – Yuvraj Agarkar Jun 27 '23 at 10:40
  • 1
    @YuvrajAgarkar please see the part about domain-matching - when you set a cookie, the `domain` attribute must be valid. So for example you cant set a cookie from https://setcookie.net with `domain=a.setcookie.net`. Your cookie's `domain` attribute must be a substring of the `Host`. – cmbuckley Jun 27 '23 at 10:46
  • so in this example what should be my domain if i set from setcookie.net with domain = `a.setcookie.net` because a.setcookie.net is my frontend for this domain to work should i make my frontend to a.a.setcookie.net ??? – Yuvraj Agarkar Jun 27 '23 at 10:50
  • when you say host, do you mean backend host i.e. the host where i set the cookie ? @cmbuckley – Yuvraj Agarkar Jun 27 '23 at 10:56
  • It sounds like you should ask a separate question if you’re unsure. But you should read the first link about host-only cookies. – cmbuckley Jun 27 '23 at 22:10
139

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:

  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.example.com domain-matches example.com, but example.com does not domain-match subdomain.example.com

Check this answer also.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Accountant م
  • 6,975
  • 3
  • 41
  • 61
  • 3
    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
  • this how i understand it and it works local setup but once I deploy to Test environment, then cookie no longer is being set unless i remove the domain attribute, please if you can have a look at my question here https://stackoverflow.com/questions/69865370/httponly-cookie-not-working-when-i-use-the-domain-attribute-with-a-subdomain-val – Carlos Jaime C. De Leon Nov 06 '21 at 15:51
  • 1
    It's worth pointing out that you can set a cookie on any superdomain up to but not including the TLD. So for instance you can't use `domain=com`. This is fairly obvious, but there are a list of domains that can't be used: https://publicsuffix.org – cmbuckley Nov 19 '21 at 12:32
48

I'm not sure cmbuckley's 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 and for those that missed it in his answer like me; worth scrolling up.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
akostadinov
  • 17,364
  • 6
  • 77
  • 85
  • 5
    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
  • 1
    thanks for the cmbuckley link. nice to test how it works quickly. – Laurence Jan 21 '19 at 14:50
  • 1
    Upvote for pointing out the test site again. – zylstra Apr 18 '22 at 00:44
31

Here is an example using the DOM cookie API, so we can see the behavior for ourselves.

If we execute the following JavaScript code,

document.cookie = "key=value"

it appears to be the same as executing:

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

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


Now, if you execute the following JavaScript code on example.com,

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

the cookie key becomes available to example.com as well as subdomain.example.com.


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

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

does the cookie key become available to subdomain.example.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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
gx0r
  • 4,682
  • 2
  • 23
  • 24
  • 2
    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
  • 4
    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
  • When setting example.com cookie from subdomain.example.com with `document.cookie = "key=value;domain=.example.com"` The cookie will only appear on subdomain.example.com. It won't show up on subdomain2.example.com or example.com. – zeroliu Oct 22 '22 at 08:15
  • 1
    @zeroliu which browser did you test that on? That is not how it works in modern browsers. Test this at https://subdomain.setcookie.net/ – cmbuckley Nov 23 '22 at 11:48
  • @cmbuckley kindly note that the behavior on your website with chrome/firefox can be misleading. When the server sends the cookie on domain "setcookie.net", firefox/chrome set actually a cookie on ".setcookie.net". The cookie is then visible on the sub domain. Updating in the dev tools the cookie to "setcookie.net" change the visibility of the cookie. Not a issue of your site. – Nicolas Labrot Feb 15 '23 at 12:48
  • 1
    @NicolasLabrot as you say, that's how those browsers are choosing to show it in their dev tools - a leading dot just means it's *not* a host-only cookie. I find that [EditThisCookie](https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg) does a better job of displaying this. – cmbuckley Feb 15 '23 at 16:34
6

Be careful if you are working on localhost! If you store your cookie in JavaScript 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 VirtualHost. For example, you can configure your virtual host with ServerName localhost.com, and then you will be able to store your cookie on your domain and subdomain like this:

document.cookie = "key=value;domain=localhost.com"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lenny4
  • 1,215
  • 1
  • 14
  • 33
4

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

The other answers add valuable insight, but they chiefly describe the behaviour in Chrome. It's important to note that the behaviour is completely different in Internet Explorer. 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 Internet Explorer shows that they are shared. This Internet Explorer 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 Internet Explorer and the two systems fought over whose session cookie would win until we blew up the cache.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
DannyW
  • 101
  • 3
-1

I do this and it works for me:

Cookie.set('token', 'some jwt-token', { expire:50000, domain: 'example.com' })
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Krishna Jangid
  • 4,961
  • 5
  • 27
  • 33
  • 3
    How does that answer the question? - *"Can example.com (without the www subdomain) access the cookie if created in subdomain.example.com?"*. E.g., where does the sub domain come in? Can you elaborate? What system was this tried on? Browser, actual website, what programming language (PHP? JavaScript?), in what environment (e.g., web framework), all incl. versions. Please respond by [editing (changing) your answer](https://stackoverflow.com/posts/72435787/edit), not here in comments (****** ***without*** ****** "Edit:", "Update:", or similar - the answer should appear as if it was written today) – Peter Mortensen Dec 08 '22 at 21:44