Subject: Cookie crumbling in -09

From: Martin Thomson <[email-masked]>
Date: Fri, 15 Nov 2013 11:52:02 -0800

I've just added some text to the editor's draft [1] around special
handling of the cookie header field.  This will allow clients to
squeeze out a little more compression efficiency.

After the gaffe earlier this week with -08, I wanted to publicize this
a little.  This is the only substantial change between -07 and the
imminent -09 in the main specification.

There are, of course, other compression-related changes coming in HPACK.

[1] https://github.com/http2/http2-spec/commit/b9a62379e29174bada803fb27e2a6d36b69513f0

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 16 Nov 2013 09:02:13 +0100

Hi Martin,

> [1] https://github.com/http2/http2-spec/commit/b9a62379e29174bada803fb27e2a6d36b69513f0

This part looks strange to me :

  If there are multiple Cookie header fields after decompression,
  these MUST be concatenated into a single octet string using the
  two octet delimiter of 0x3B, 0x20 (the ASCII string "; ").

Indeed, right now applications correctly handle cookie as a list
of values which can be aggregated using commas like any other header
field. Thus, why make a special case of this cookie header and force
implementations to parse requests to see if there are multiple
occurrences and merge them differently than what is done for other
header fields ? I'd rather suggest that if there are multiple Cookie
header fields after decompression, they MAY be concatenated into a
single octet string using commas just like any other header field
(0x2C 0x20).

What do you think ?

Willy

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 16 Nov 2013 09:22:26 +0100

> single octet string using commas just like any other header field

Or maybe even better, we could probably say that the headers MAY
preferentially be concatenated using 0x3B 0x20, though the default
header field folding using 0x2C 0x20 is fine as well. At least we
allow implementations to restore what they found on the input in
the case the cookies were all on a single line emitted by a browser
using semi-colons.

Willy

---

From: Mike Bishop <[email-masked]>
Date: Sat, 16 Nov 2013 18:47:27 +0000

Except that there's nothing on the wire communicating which form was used; "restoring" doesn't seem possible without communicating that.  An implementation will probably always do one or the other.

-----Original Message-----
From: Willy Tarreau [mailto:[email-masked]] 
Sent: Saturday, November 16, 2013 12:22 AM
To: Martin Thomson
Cc: HTTP Working Group
Subject: Re: Cookie crumbling in -09

On Sat, Nov 16, 2013 at 09:02:13AM +0100, Willy Tarreau wrote:
> > After the gaffe earlier this week with -08, I wanted to publicize 
> > this a little.  This is the only substantial change between -07 and 
> > the imminent -09 in the main specification.
> > 
> > [1] 
> > https://github.com/http2/http2-spec/commit/b9a62379e29174bada803fb27
> > e2a6d36b69513f0
> 
> Indeed, right now applications correctly handle cookie as a list of 
> values which can be aggregated using commas like any other header 

Or maybe even better, we could probably say that the headers MAY preferentially be concatenated using 0x3B 0x20, though the default header field folding using 0x2C 0x20 is fine as well. At least we allow implementations to restore what they found on the input in the case the cookies were all on a single line emitted by a browser using semi-colons.

Willy

---

From: Martin Thomson <[email-masked]>
Date: Sun, 17 Nov 2013 16:44:19 -0800

On 16 November 2013 00:02, Willy Tarreau <[email-masked]> wrote:
> field.

All the discussions thus far, plus a reasonably careful reading of RFC
6265 leads me to conclude that this is not the case.  In particular,
http://tools.ietf.org/html/rfc6265#section-5.4 is quite clear:

   When the user agent generates an HTTP request, the user agent MUST
   NOT attach more than one Cookie header field.

Given the grammar, which doesn't use the list construction or a comma,
merging with commas would seem to be invalid.

I'd be interested in learning if multiple headers appeared ever in the wild.

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 18 Nov 2013 05:52:03 +0100

Hi Martin,

>    NOT attach more than one Cookie header field.

Indeed, I'm noticing this change in this version. Both 2109 and 2965 used
to define it this way using ';' or ',' as delimiters :

  cookie          =  "Cookie:" cookie-version 1*((";" | ",") cookie-value)

I have no idea why Adam proposed this change in a way incompatible with
what was done for 15 years. Also I know a number of places where reverse
proxies add Cookie headers before passing the request to the server
(generally with user information or geoloc info). It's been said for a
while that only the Set-Cookie header could not be folded (because of the
date containing a comma) while the Cookie header can.

> merging with commas would seem to be invalid.

It used to be before 6265 at least.

> I'd be interested in learning if multiple headers appeared ever in the wild.

Well, I don't know if browsers do this, I doubt it. I know at least one
component at a customer's which splits cookies over multiple lines to
avoid emitting more than 8kB per line. I would not be surprized if we
could find a few other ones.

That said, as soon as you propose to split the Cookie header values into
multiple header fields and to re-aggregate them afterwards, you're doing
exactly that.

If we want to be able to split values following semi-colons in HTTP/2
(usually they're just "attributes" of a value), we should probably invent
a specific encoding for this. Or instead, we should go further and define
how cookies should be converted to some HTTP/2-specific state management
and conversely.

Best regards,
Willy

---

From: Julian Reschke <[email-masked]>
Date: Mon, 18 Nov 2013 09:30:10 +0100

>    cookie          =  "Cookie:" cookie-version 1*((";" | ",") cookie-value)

But that's not the "list" rule that 
<http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-25.html#rfc.section.3.2.2.p.2> 
refers to.

> date containing a comma) while the Cookie header can.

As far as I remember, this didn't come up while the httpstate WG worked 
on the new cookie spec.

> It used to be before 6265 at least.

Nope, see above.

> ...

Best regards, Julian

---

From: Daniel Stenberg <[email-masked]>
Date: Mon, 18 Nov 2013 09:42:26 +0100 (CET)

On Mon, 18 Nov 2013, Willy Tarreau wrote:

> Indeed, I'm noticing this change in this version. Both 2109 and 2965 used to 
> define it this way using ';' or ',' as delimiters :

...

> I have no idea why Adam proposed this change in a way incompatible with what 
> was done for 15 years.

2109 and 2965 were never used to any particular extent and thus don't tell how 
cookies were used.

RFC 6265 was made by figuring out and documenting how cookies actually were 
used by the existing cookie implementations used on the internet to the best 
of the abilities of us who participated, not only Adam...

-- 

  / daniel.haxx.se

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 18 Nov 2013 09:56:33 +0100

> <http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-25.html#rfc.section.3.2.2.p.2> 

Good catch, I didn't notice the "cookie-version" part that's mentionned
as mandatory here while almost nobody sends it (one more reason for 6265
to rely on use cases BTW).

> As far as I remember, this didn't come up while the httpstate WG worked 

I participated a little bit near the end when I noticed there was some
ongoing work on this and didn't notice the disparition of the comma, it
was so obvious to me that cookies "remained" defined as a list...

> >It used to be before 6265 at least.

It's a bit more complicated in fact. What happens is that folding cookie
header fields using commas used to work with previous parsers because
they used to support both the semi-colon and the comma and didn't care
about the $Version which was not part of the initial spec from Netscape.
Now since the original spec did not propose the comma as a delimiter, it
is indeed possible that some implementations prior to 2109 do not even
support it. That might be the reason the comma was finally removed from
6265. Definitely a sad situation.

So that probably goes in the direction of dealing specifically with
semi-colon delimited values in HTTP/2 without considering that, as a
special case, we split the Cookie header in multiple occurrences on
one side to fold it on the other side.

Ideally some cleaner state management would significantly help so that
this Cookie/Set-Cookie hell only affects 1.1-2.0 gateways and not at all
any end-to-end 2.0 communication.

Best regards,
Willy