Share cookies between subdomain and domain
Asked Answered
L

6

737

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?

Lyrism answered 28/8, 2013 at 15:46 Comment(6)
Yes you can.. please see link below codeguru.com/csharp/csharp/cs_internet/article.php/c19417/…Pointing
Closely related: #3089699Kelliekellina
can you please look at this question #38352269Hinny
@Lyrism What if domain and sub domain are hosted on different server ?Hellenistic
@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).Lyrism
Small note about SameSite, which seems like "could" answer the question because MDN talks there about cross-origin requests.. But no, it is not cross-origin in the CORS sense, so SameSite doesn't affect root and subdomain cookie relation. See security.stackexchange.com/questions/223473/… .Repair
F
1126

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. Some browsers will show a leading dot in developer tools to differentiate between host-only cookies and other cookies, but this is for display purposes only.

Forwards answered 15/4, 2014 at 14:7 Comment(39)
So I had two questions in my original post. Are you saying the answer is "yes" to both, but only on newer browsers?Lyrism
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?Angers
I don't understand why you wouldn't just put the leading "." on the domain for maximum compatibility with old and newLepley
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.Forwards
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.Sankhya
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?Forwards
@adam: technically www IS a subdomain, it's a special kind of subdomain, at least from the point of view of DNS servers.Endurable
@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.Lyrism
@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.Walt
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=<future expiry date>"Montserrat
@Montserrat 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 covers the matching logic.Forwards
What if the cookie is created in sub1.mydomain.com, with the domain set to mydomain.com does sub2.mydomain.com then have access?Reinaldoreinaldos
@shi Yes - please see the last sentence: "This can also be used to allow sub1.mydomain.com and sub2.mydomain.com to share cookies."Forwards
@Forwards i thought so, i am hitting a wall here #56561424Reinaldoreinaldos
if no . some one could use afacebook.com and get all cookies as the . is not separating the wildcardOasis
@WalterVehoeven that's not how the domain matching works - see RFC 6265 § 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.Forwards
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.Meredeth
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?Subdivide
@Subdivide yes - read the final paragraph of the post about sub1 and sub2 being able to share cookies.Forwards
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.Adjunct
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.Forwards
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 linksModulator
@Forwards 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?Holdall
@Holdall 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.Forwards
"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.Holdall
@Holdall the first statement is already in the answer, and whilst a comment here led me to believe IE8/9 might behave differently, subsequent testing suggests that might not be true.Forwards
How can i set the cookie, only for a specific sub domain, I dont want all subdomains to access it ???Puseyism
@YuvrajAgarkar the only way to do this would be to set a cookie from the subdomain. For example if you set a cookie on a.setcookie.net, you can restrict it to that subdomain (either choose a.setcookie.net or unspecified as the domain).Forwards
@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 urlPuseyism
@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 setcookie.net with domain=a.setcookie.net. Your cookie's domain attribute must be a substring of the Host.Forwards
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 ???Puseyism
when you say host, do you mean backend host i.e. the host where i set the cookie ? @ForwardsPuseyism
It sounds like you should ask a separate question if you’re unsure. But you should read the first link about host-only cookies.Forwards
mydomain doesn't work with this strategy, but mydomain.com doesPore
Is it true that any subdomain can set the cookie for the top-level domain, which will then overwrite the same-named cookies for every other subdomain? Seems horribly insecure! So anyone can basically do a session-fixation attack on my subdomain, as long as there is a DNS record for their subdomain? How would someone even mitigate something like this? The cookie can change at any time!Illiterate
@GregoryMagarshak in a multi-user scenario, the top-level domain should be on the public suffix list which prevents setting such privacy-damaging cookies.Forwards
I am talking about subdomains of a regular domain, not a top-level domain. Such as foo.geocities.com overwriting cookies on bar.geocities.comIlliterate
I understand what you’re saying, and it’s the responsibility of the owner of such a service to add it to the PSL to prevent what you describe. For instance, setcookie.net is hosted at setcookie.fly.dev. I cannot set a cookie on fly.dev, because the owners of that service have added it to the PSL.Forwards
I was sure that the public suffix list is for things like .co.uk not .geocities.comIlliterate
H
154

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.

Higa answered 5/9, 2019 at 10:11 Comment(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.Hatpin
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 #69865870Registration
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: publicsuffix.orgForwards
L
51

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.

Lohner answered 6/6, 2016 at 11:59 Comment(6)
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 too.Forwards
@cmbuckley, ok, what you said seems correct. I'll reword my answer. Thank you for pointing that out.Lohner
Need to point out, that section 4.1.2 (first citation) is not normative...Pestle
thanks for the cmbuckley link. nice to test how it works quickly.Hulburt
Upvote for pointing out the test site again.Huskey
great test site!Deprave
R
30

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.

Rationale answered 26/9, 2017 at 19:45 Comment(7)
This makes me wonder if there are separate specs describing the behavior of httponly cookies versus the kind of cookies you are creating.Lyrism
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.Forwards
this is the best solution if you don't want to rely on host headers. I checked it and its workingSubtotal
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.Equestrienne
@Equestrienne which browser did you test that on? That is not how it works in modern browsers. Test this at subdomain.setcookie.netForwards
@Forwards 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.Daiquiri
@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 does a better job of displaying this.Forwards
R
8

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"
Rhatany answered 16/12, 2019 at 20:20 Comment(2)
AHA! Maybe this is my issue.Bielefeld
On windows, you can just modify your hosts file and set whatever alias you want for localhost. For example, local.mydomain.com.Lyrism
C
3

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.

Concert answered 6/6, 2017 at 5:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.