Code change:
This patch alters the cookie parsing algorithm to treat as creating a cookie with an empty name and a value of "token". It also rejects cookies with neither names nor values (e.g. and . Tests in web-platform-tests/wpt. Closes httpwg/http-extensions.
NAME Ping?
Landing this based on the discussion in . NAME If the wording needs more cleanup, I'd appreciate feedback!
The cookie-pair ABNF rule still requires presence of . Is it intentional?
As a part of discussion in whatwg/html I've made a of the modern browsers compatibility with the RFC 6265. It appears that all browsers nowadays allows cookies without key or (in case of Safari) without value, thus making it de facto standard. However, it's debatable how cookies like should be treated: as the cookie without value or without key. Thinking of cookie jar as some kind of key/value store makes it more logical to treat such cookie as cookies without value, but on the other hand, currently most implementers treats them as the cookies with the special empty key.
Discussed at Berlin IETF; Julian points out that we should check previous discussion in cookie WG. Martin points out that we should talk to the implementation that has divergent behaviour.
Context: around URL, ticket in URL
For clarity, are we saying Chrome, Firefox, and Edge treat such a cookie as key: "" and value "foo", and Safari treats it like key: "foo" and value: ""?
Per the table linked in OP Safari serializes input as whereas others serialize as . Firefox attempted to be more strict on cookie setting lacking and found it broke a router: URL
URL is the relevant test, in particular the following subtests: sends . Chromium stores a cookie with an empty name and value of , serialized as . Firefox does the same. Safari drops the cookie entirely. Given Firefox's experience with and related bugs above, this seems like it might be baked into some user-visible sites that are unlikely to update. I'd suggest that we change this test expectation to , and update the spec accordingly. sends , , and . Chromium stores three cookies: , , and , serialized as . Firefox and Safari store two cookies: and , serialized as . The latter is clearly correct and matches the spec; filed URL to change Chromium's behavior. sends , , and . Chromium stores three cookies: , , and , serialized as . Firefox does the same. Safari stores two cookies: and , serialized as . If we change 0004 above, then we'd update this test as well to match Chromium and Firefox. sends , , and . Chromium stores three cookies: , , and , serialized as . Firefox does the same. Safari also stores the same three cookies, but serializes them as . I think this ordering problem is similarly represented in and , and is something that can be dealt with separately from this issue. sends and . Chromium stores , and then overwrites it with . Firefox stores and ignores the empty cookie. Safari ignores both (as per 0004 and 0021 above). I think Firefox's behavior is most correct here as a logical consequence of the spec change to fix 0004, and I believe Chromium will match it once the bug filed for 0020 above is addressed. sends and . Chromium stores , and then overwrites it with . Firefox does the same. Safari ignores both. If we change 0004 as above, then Firefox and Chromium's behavior will match the spec, and the test should be updated. I'll put up a PR against the spec if folks are on board with the suggestions above.
Putting together a , I ran into more excitement: 0024 (, ), 0025 (, ), and 0026 (, ) show that Firefox overwrites with , and serializes it as "". 0028 would show the same, but it's incorrect in the WPT repository; it should contain a tab character, and the expectations are simply wrong (also in the original repo). I'd suggest that this behavior doesn't make much sense, and that it would be better for browsers to align on requiring cookies to have either a name or a value, and to ignore headers that parse with empty names and empty values. That would change the expectations for these four tests to expect a serialization of "Cookie: foo". WDYT, NAME NAME
For clarity: https://chromium-URL shows the test expectations I'd suggest we end up with.
Tl;dr: I think changing the spec to match current implementations for to produce (i.e. 0004 case) makes sense. I think disallowing (0020 case) and (0023 case) would make sense too, but that might break things. In the 0004 case: We've been parsing as an empty name with a non-empty value for a long time, afaict. Since Firefox seems to do the same thing, I think we should definitely update the spec to match the implementations (i.e. for a Set-Cookie line without a but with a valid token, treat the token as the value and, for cookies without a name, don't put a when serializing). In the 0020 () and 0023 (empty ) cases: Judging by Chrome metrics for Cookie.HeaderLength, there is definitely non-zero usage of empty cookies, so I'm concerned that rejecting empty cookies would break things... (In the 0020 case, one could also argue that explicitly sending a Set-Cookie header of indicates intent to create a cookie, even if it is empty.) I agree it's a bit silly to allow cookies with both empty name and empty value, though. I think that's a reasonable change to make to the spec, and maybe we don't care about potentially breaking things.
Thanks, NAME I agree with you for the 0004 case. NAME would Apple be willing to change CFNetwork's behavior to match the suggestions above? For 0020 and 0023: Looking at the stable channel on for the 28 days ending on Dec 31st, 0.0025% of headers were empty, spread over 0.12% of users. This is a pretty small number in total, and a pretty small number per user; certainly within the range of changes we've been successful with in the past. I wouldn't be surprised if it broke something (because everything we do with cookies breaks something!), but I would be surprised if it broke anything critical enough to retain the behavior. It would signify an intent to create a cookie without a name and without a value. What would that intent mean? I'd like it to mean "Don't create a cookie." :)
I'm okay with your proposed changes. cc NAME NAME NAME
URL should cover the proposed changes above. (I kinda want to rewrite the whole parsing algorithm in terms of Infra to be a bit more precise, but that's a task for another patch. :) )
I’ve pinged the relevant folks to take a look at this thread. Like me, many won’t be back until Monday.
Not sure if it's the same thing, but I've seen facebook send an empty header frequently. For example visiting URL loads a 1 pixel gif with the following URL: URL (replacing XXXX with your unique tracking reference) with the following response headers (note the blank header, third from the bottom): This then gets set in the Chrome Cookie jar with the following: ! I can't seem to find this showing in Firefox's cookie jar (even when turning off the default Enhance Tracking Protection) nor in Safari. Anyway, I'm sure a good few of us wouldn't care if this "cookie" died a death, or if Chrome changed to ignore this "cookie", and not even sure if it DOES anything (it doesn't seem to be sent in follow up HTTP requests, but that's not to say it's not looked at by some local JavaScript). However, given the prevalence of Facebook tracking I'm really surprised these sorts of cookies are only seen by 0.12% of users so thought I'd comment to note this in case those estimates are not accurate? Perhaps the stats are not picking up these cases? I've seen this on many sites and only picked the Guardian as a well-known example and guessed first time it would be on there (news sites are good ones to pick when looking for tracking pixel examples!). URL sets the same if you prefer something US based and URL sets the same (but not on the main domain) for those of you in that side of the world.
The number of 0-byte Cookie headers is only a lower bound on how many no-name-no-value cookies are in use. If such a cookie were sent along with some other cookies, it would not be logged as a 0-byte header. I don't think we have any metrics on per-cookie length, just the total length of the Cookie header. So it might be worth collecting more data? Also, that metric doesn't include cookies accessed via .
Regarding NAME comments on Facebook; I pinged someone there who will forward this to the appropriate team. It sounds like a bug to me, and not something that I think should stop us from making a decision here on the underlying question of whether an empty cookie is a thing we should support. NAME I read your comments above as generally approving of the change suggested in URL, but cautious about how to ship it in Chrome? That feels like an important part of an eventual "Intent to Ship", rather than a discussion of what we'd like the spec to say. If we decide to accept the suggestions above, then I'm pretty confident that we can work out how and when to ship it (especially given that there's no real agreement among browsers today, so the status quo is already trifurcated as per URL above). Indeed! You're exactly right, and I should have been more clear. The 0.0025% is the number of requests (not page views, FWIW) for which we'd shift from sending an empty header to sending no header at all. That seems to me to be a change more likely to invalidate an application's expectations than shifting from to . I think this is the easier case, actually, as the serialization of an empty cookie is indistinguishable from a empty cookie jar.
Thanks for sending on NAME . I more meant it as a concern that the 0.12% of users figure sounds way too low to me given Facebooks prevalence. Note you don’t need to be a Facebook user or visit a Facebook site to get this cookie - just a site that uses Facebook advertising pixels (of which there are many!). So I still have that concern that this figure sounds way too low to me. Which then begs the question as to whether there are more cases than we think there are? Now I agree that particular example sounds like a bug and I doubt this empty cookie is being used and so don’t think blocking it off will cause a breakage, but still, I’m uneasy that the stats seem wrong and that we are using this (potentially incorrect) stat to justify the low chance of breakage with this change. There might be other cookies on other sites that will cause breakage. To be clear, I don’t actually think it will cause a lot of breakage, but would rather than was based on a stat we are comfortable to stand behind than one that we have potential concerns with. Is there any way to double check that 0.12% stat given this example? Maybe a lot less users than I think are getting this cookie but given I’ve spotted it on 3 major news paper sites in 3 distinct countries, without having to look too far for these examples, makes me suspect that is not the case. says Facebook assets are being used on 2.38% of the most used 5.7 million sites and I’d guess they all come with some cookies for free. And that stat treats each of those 5.7 million sites equally when actual usage will be heavily skewed to the sites at the top end than the tail so usage will likely be more than that as top end sites are more likely to use Facebook advertising in my opinion. And again, I’m not concerned with this Facebook example - but more that it seems to suggest the 0.12% stat feels wrong. Or maybe it’s not being included since this empty cookie doesn’t seem to be sent in follow up requests, and that’s what that stat is measuring? If that’s the reason, and we’re comfortable with that explanation and the risks that entails (I am for what it’s worth), then that’s fine, but thought it worth asking the question.
As NAME notes above, we don't have statistics on cookie size generally; just aggregate numbers on header length. The "0.12% of users" statistic is the set of users who have ever sent an empty header (e.g. the only cookie they have for a given request is empty). If nameless/valueless cookies are set for other sites, they'll be serialized as , which we don't track specifically. I noted above that I'm less concerned about this case than I am about the "We used to get a header, but now we don't get anything at all!" case, but I'm honestly not terribly concerned about either given the existing diversity in the way browsers handle .
OK makes sense. Thanks for answering.
Yes, that's right.
The CFNetwork team approves of the change and is tracking the work in rdar://problem/58358759.
Given that, I'd suggest that we land something like URL along with the tests from https://chromium-URL Thanks! If you'd like to improve compatibility with IE and Firefox, you might consider representing these as nameless cookies instead of valueless cookie. You can observe the difference via test 0027: Set-Cookie: foo Set-Cookie: bar

Related discussion:
text: contained in the set-cookie-string, and the unparsed-attributes is the empty string. <del> If the name-value-pair string lacks a %x3D ("=") character, ignore the set-cookie-string entirely. </del> <ins> If the name-value-pair string lacks a %x3D ("=") character, then the name string is empty, and the value string is the value of name-value-pair. </ins> <del> The (possibly empty) name string consists of the characters up to, but not including, the first %x3D ("=") character, and the (possibly empty) value string consists of the characters after the first %x3D ("=") character. </del> <ins> Otherwise, the name string consists of the characters up to, but not including, the first %x3D ("=") character, and the (possibly empty) value string consists of the characters after the first %x3D ("=") character. </ins> Remove any leading or trailing WSP characters from the name string and the value string. <del> If the name string is empty, ignore the set-cookie-string entirely. </del> <ins> If both the name string and the value string are empty, ignore the set-cookie-string entirely. </ins> The cookie-name is the name string, and the cookie-value is the value string.