114

Say for example I had an application sending the following HTTP headers to set to cookie named "a":

Set-Cookie: a=1;Path=/;Version=1
Set-Cookie: a=2;Path=/example;Version=1

If I access /example on the server both paths are valid, so I have two cookies named "a"! Since the browser doesn't send any path information, the two cookies cannot be distinguished.

Cookie: a=2; a=1

How should this case be handled? Pick the first one? Create a list with all cookie values? Or should such a case be considered as a developer's mistake?

deamon
  • 89,107
  • 111
  • 320
  • 448
  • 2
    I would do my best (read: everything I can) to avoid duplicate cookie names. Most people have never run into this issue -- for good reason. –  Oct 29 '10 at 22:27
  • Website can only read its own cookie. It cannot read cookie of the other website/domain. This security is ensured by browser. This may be a tip for absolute beginners ( I had this confusion ) – Arun Aug 14 '20 at 01:32
  • 3
    @Arun - but it can read subdomains. And that's where the confusion usually comes from – avalanche1 Nov 18 '21 at 20:06

7 Answers7

114

The answer referring to an article on SitePoint is not entirely complete. Please see RFC 6265 (to be fair, this RFC was released in 2011 after this question was posted, which supersedes previous RFC 2965 from 2000 and RFC 2109 from 1997).

Section 5.4, subsection 2 has this to say:

The user agent SHOULD sort the cookie-list in the following order:

  • Cookies with longer paths are listed before cookies with shorter paths.

NOTE: Not all user agents sort the cookie-list in this order, but this order reflects common practice when this document was written, and, historically, there have been servers that (erroneously) depended on this order.

There is also this little gem in section 4.2.2:

... servers SHOULD NOT rely upon the serialization order. In particular, if the Cookie header contains two cookies with the same name (e.g., that were set with different Path or Domain attributes), servers SHOULD NOT rely upon the order in which these cookies appear in the header.

In your example request cookie (Cookie: a=2; a=1) note that the cookie set with the path /example (a=2) has a longer path than the one with the path / (a=1) and so it is sent back to you first in line, which matches the recommendation of the spec. Thus you are more or less correct in your assumption that you could select the first value.

Unfortunately the language used in RFCs is extremely specific - the use of the words SHOULD and SHOULD NOT introduce ambiguity in RFCs. These indicate conventions that should be followed, but are not required to be conformant to the spec. While I understand the RFC for this quite well, I haven't done the research to see what real-world clients do; it's possible one or more browsers or other softwares acting as HTTP clients may not send the longest-path cookie (eg: /example) first in the Cookie: header.

If you are in a position to control the value of the cookie and you want to make your solution foolproof, you are best off either:

  1. using a different cookie name to override in certain paths, such as:
  • Set-cookie: a-global=1;Path=/;Version=1
  • Set-cookie: a-example=2;Path=/example;Version=1
  1. storing the path you need in the cookie value itself:
  • Set-cookie: a=1&path=/;Path=/;Version=1
  • Set-cookie: a=2&path=/example;Path=/example;Version=1

Both of these workarounds require additional logic on the server to pick the desired cookie value, by comparing the requested URL against the list of available cookies. It's not too pretty. It's unfortunate the RFC did not have the foresight to require that a longer path completely overrides a cookie with a shorter path (eg: in your example, you would receive Cookie: a=2 only).

Community
  • 1
  • 1
  • 2
    Thank you for digging this out from these damn RFCs! //why even bother reading them if no one is following these recommendations?.. – Rast Sep 03 '14 at 07:00
  • 3
    It looks like Wildfly 8.0 is paying attention to the order of the cookies and uses the first one. This allows us to run another app in a 'nested' context. However, it would fail if some browsers don't follow RFC's recommendation. Correct way to do this to set different name of the session cookie, like JSESSIONID2. – honzajde Jan 21 '15 at 12:44
  • 5
    I did test the major browsers after reading your answer: Chrome 63 / Opera 55 / IE11 / Edge 16 / Safari 11 / Firefox 58 And they all seems to handle it correctly that the Cookie with longer path are before the one with shorter path. And in PHP (tested on version 7) it only read the first cookie which is set to the $_COOKIE variable. – Alexander Schranz Feb 12 '18 at 18:56
  • 1
    Does `path=/;Path=/` specification conforms FRC-6265? I did not found such mention. [Tomcat](https://fossies.org/linux/apache-tomcat/java/org/apache/tomcat/util/http/Rfc6265CookieProcessor.java#l_221) threat any ";" in path as incorrect symbol – Hubbitus Dec 08 '18 at 16:39
  • 1
    @Hubbitus Pay attention, it’s `a=2&path=/example;Path=/example` so there is no `;` in path. – Franklin Yu Jun 28 '19 at 15:20
  • It seems strange that (unless I am wrong) the spec doesn't allow for the path to be specified in the request header, but does allow multiple cookies with the same name and different values, making no sense. But we can use the fact that browsers send this to our advantage. If the server receives such, we probably have a bug in our code, and can log an 'error'. Most likely we forgot to specify the path in the `Set-Cookie` header, and the [default path](https://tools.ietf.org/html/rfc6265#section-5.1.4) assigned was not what we intended (it is not `/`!). – Jake Mar 14 '20 at 01:39
43

From this article on SitePoint:

If multiple cookies of the same name match a given request URI, one is chosen by the browser.

The more specific the path, the higher the precedence. However precedence based on other attributes, including the domain, is unspecified, and may vary between browsers. This means that if you have set cookies of the same name against “.example.org” and “www.example.org”, you can’t be sure which one will be sent back.

Edit: this information from 2010 appears to be outdated, it seems browsers can now send multiple cookies in return, see answer by @Nate below for details

Community
  • 1
  • 1
Jan M
  • 2,205
  • 21
  • 14
  • 16
    So how can one delete the multiple identical cookies? I have hammered on this for two days now and the duplicate cookies seem indestructible. – Bob Jones Aug 07 '12 at 23:14
  • 15
    @Brant That article may be slightly incorrect -- I just saw Chrome send two cookies of the same name (but different paths) back, so "one is chosen by the browser" is not necessarily true. The deepest path cookie was sent first, BTW, which seems reasonable. And another cookie made it in between, too. – Jonas N Aug 31 '12 at 23:22
  • 4
    Firefox (15) also sends two cookies with the same name! if it encountered with two cookies with for domain `.a.com` and host `a.com` – Taha Jahangir Sep 16 '12 at 16:35
  • 1
    Indeed this information is wrong. @Nate 's answer should me marked as correct. – Dan Milon Dec 05 '14 at 13:50
  • @BobJones Did you figure out how to delete those duplicate cookies? – Sush Jul 01 '19 at 17:44
  • 8
    404: The famous @Nate's answer is not found. – d.popov Sep 16 '19 at 12:59
  • this is how I have been able to "delete" cookies when expiring them didn't do the trick: HttpContext.Current.Response.Cookies.Remove("cookiename") – MikeDev Aug 11 '20 at 15:00
4

@user2609094 clarifies the behaviour around paths, so I thought I'd add a quick answer for the behaviour around domains (which is unspecified).

If you create cookies for a domain and subdomain ("foo.example.org" and "example.org") with the same name then the browser will send both cookies, with no indication of which one is which. Additionally, the order does not appear to be based on which domain is more specific. From testing in Google Chrome, the cookies are simply sent in the order they were created - so you can't make any assumptions about which one is which.

Gh0stFish
  • 301
  • 1
  • 2
  • 7
2

There is nothing wrong with having multiple values for the same name... if you want them. You might even embed additional context in the value.

If you don't, then of course different names are a solution if you want both contexts.

The alternative is to send the same cookie name with the same path (and domain) even from the more specific paths. Those set cookie instructions will overwrite the value of that cookie.

Now that you know the most important part (how they work), and that you can accomplish what you need in a few different ways, my answer to your question is: this is a developer issue.

Gerard ONeill
  • 3,914
  • 39
  • 25
0

I'm certainly aware of applications which do this extensively using multiple session ids - and seem to work consistently. However I don't know - and have no intention of finding out - if they do so because the browser returns the cookies in a consistent order depending on when they were set / which path they were set for or whether the app tries to match each one to an existing session.

I would strongly recommend that this practice be avoided.

However if you really want to know how the browsers (and apps) handle this scenario, why not build a test rig and try it out.

symcbean
  • 47,736
  • 6
  • 59
  • 94
0

If you use the Java/Scala framework Play: watch out! If a request contains multiple cookies with the same name, Play will only present 1 of them to your code.

Erik van Oosten
  • 1,541
  • 14
  • 16
-3

If you need to distinguish them you have to give them different key values.

Yoghurt
  • 31
  • 2