Specifically, a site may match Version 0 cookies from one site, and Version 1 cookies from another. The Cookie header then to be sent by a client is ill-defined.
The Cookie header specified in RFC 2965 (and earlier in RFC 2109) begins with a cookie-version, and then with a semicolon- or comma-separated representation of cookies.
Hypothetically, two distinct headers (one for Version 0 cookies and one for Version 1 cookies) might be sent. On the other hand, in section 7.2 (Cookie Spoofing) of RFC 2965, a header is presented in which the substring
$Version="1";
is placed in front of each of two cookies in a single header.
Perhaps the version specification could be taken to be that of the highest-version sent; but alternately it might be taken to be that of the lowest version sent.
I have sent e.mail to Lou Montulli (one of the authors), but he has not responded. (I suspect that he has not received my message.) I have attempted to sent e.mail to David M. Kristol (the other author), but Bell Labs declares his address invalid. I have written to the IETF, but they have not responded.
"Daniel Kian Mc Kiernan" <Mc-Kier...@bogus-subdomain.worldnet.att.net> writes:
[...]
> The Cookie header specified in RFC 2965 (and earlier in RFC 2109) begins > with a cookie-version, and then with a semicolon- or comma-separated > representation of cookies.
> Hypothetically, two distinct headers (one for Version 0 cookies and > one for Version 1 cookies) might be sent. On the other hand, in > section 7.2 (Cookie Spoofing) of RFC 2965, a header is presented in > which the substring
> $Version="1";
> is placed in front of each of two cookies in a single header.
Yes, and note the ", " separating them. Duplicate MIME headers can be folded together, and there is no requirement that the $Version value be the same for each "Cookie" header.
I don't see any problem here wrt RFC 2965. AFAICT the example in section 7.2 is just a consequence of the HTTP specs.
On 28-Nov-2002, the incomparable Joe Schaefer <joe+use...@sunstarsys.com> wrote:
>> The Cookie header specified in RFC 2965 (and earlier in RFC 2109) begins >> with a cookie-version, and then with a semicolon- or comma-separated >> representation of cookies.
>> Hypothetically, two distinct headers (one for Version 0 cookies and >> one for Version 1 cookies) might be sent. On the other hand, in >> section 7.2 (Cookie Spoofing) of RFC 2965, a header is presented in >> which the substring
>> $Version="1";
>> is placed in front of each of two cookies in a single header.
> Yes, and note the ", " separating them.
I did, but I'm not sure what significance you want me to impute to it. The standard does not say that when a version declaration appears more than one, a comma is to be used as a separator. Indeed, the comma is specified acceptable as a separator of cookies from the _same_ original header. If this declaration is in fact acceptable, then it should be acceptable (under current standards) with a semicolon before it.
> Duplicate MIME headers can > be folded together, and there is no requirement that the $Version > value be the same for each "Cookie" header.
But we cannot always safely make an inference about HTTP headers from MIME specifications; and (by definition) distinct HTTP header types have distinct properties. RFC indeed states
An origin server MAY include multiple Set-Cookie2 headers in a response. Note that an intervening gateway could fold multiple such headers into a single header.
but
[1] That's a declaration about _server_ behavior. [2] The term "fold" isn't here defined. (In RFC 2068 (HTTP/1.1), the term fold appears in the declaration
HTTP/1.1 headers can be folded onto multiple lines if the continuation line begins with a space or horizontal tab.
from which we may infer that therein "folding" refers to a sort of _splitting_.)
[3] The only way to combine multiple headers into a single header while conforming to the specification of the (client-sent) Cookie header (3.3.4) is to strip away the Version-specification from all but the first of the pre-folded headers (much as is the prefix "Cookie: ").
The specification is
cookie = "Cookie:" cookie-version 1*((";" | ",") cookie-value) cookie-value = NAME "=" VALUE [";" path] [";" domain] [";" port] cookie-version = "$Version" "=" value
rather than
cookie = "Cookie:" (cookie-list) *("," cookie-list) cookie-list = cookie-version 1*(";" cookie-value) cookie-version = "$Version" "=" value cookie-value = NAME "=" VALUE [";" path] [";" domain] [";" port]
or somesuch.
I also note, however, that the specifications in RFC 2965 are somewhat informal. (For example, in 3.2.2, the specification of portlist is formally incorrect.) Thus, I find it _plausible_ that the intention was that version information may be provided more than once.
> I don't see any problem here wrt RFC 2965. AFAICT the example in > section 7.2 is just a consequence of the HTTP specs.
Whatever its status with respect to the HTTP specs, it is not in keeping with the Cookie specs!
The issue of what a client is to return (when cookies of different versions match the server) needs to be addressed. And it would be best were it addressed explicitly.
Unfortunately, the parties responsible for the RFC are incommunicado.
On 28-Nov-2002, the incomparable Joe Schaefer wrote:
>> The Cookie header specified in RFC 2965 (and earlier in RFC 2109) begins >> with a cookie-version, and then with a semicolon- or comma-separated >> representation of cookies.
>> Hypothetically, two distinct headers (one for Version 0 cookies and >> one for Version 1 cookies) might be sent. On the other hand, in >> section 7.2 (Cookie Spoofing) of RFC 2965, a header is presented in >> which the substring
>> $Version="1";
>> is placed in front of each of two cookies in a single header.
> Yes, and note the ", " separating them.
I did, but I'm not sure what significance you want me to impute to it. The standard does not say that when a version declaration appears more than one, a comma is to be used as a separator. Indeed, the comma is specified acceptable as a separator of cookies from the _same_ original header. If this declaration is in fact acceptable, then it should be acceptable (under current standards) with a semicolon before it.
> Duplicate MIME headers can > be folded together, and there is no requirement that the $Version > value be the same for each "Cookie" header.
But we cannot always safely make an inference about HTTP headers from MIME specifications; and (by definition) distinct HTTP header types have distinct properties. RFC 2965 indeed states
An origin server MAY include multiple Set-Cookie2 headers in a response. Note that an intervening gateway could fold multiple such headers into a single header.
but
[1] That's a declaration about _server_ behavior. [2] The term "fold" isn't here defined. (In RFC 2068 (HTTP/1.1), the term fold appears in the declaration
HTTP/1.1 headers can be folded onto multiple lines if the continuation line begins with a space or horizontal tab.
from which we may infer that therein "folding" refers to a sort of _splitting_.)
[3] The only way to combine multiple headers into a single header while conforming to the specification of the (client-sent) Cookie header (3.3.4) is to strip away the Version-specification from all but the first of the pre-combined headers (much as is the prefix "Cookie: ").
The specification is
cookie = "Cookie:" cookie-version 1*((";" | ",") cookie-value) cookie-value = NAME "=" VALUE [";" path] [";" domain] [";" port] cookie-version = "$Version" "=" value
rather than
cookie = "Cookie:" cookie-list *("," cookie-list) cookie-list = cookie-version 1*(";" cookie-value) cookie-version = "$Version" "=" value cookie-value = NAME "=" VALUE [";" path] [";" domain] [";" port]
or somesuch.
I also note, however, that the specifications in RFC 2965 are somewhat informal. (For example, in 3.2.2, the specification of portlist is formally incorrect.) Thus, I find it _plausible_ that the intention was that version information may be provided more than once.
> I don't see any problem here wrt RFC 2965. AFAICT the example in > section 7.2 is just a consequence of the HTTP specs.
Whatever its status with respect to the HTTP specs, it does not appear to be in keeping with the Cookie specs.
The issue of what a client is to return (when cookies of different versions match the server) needs to be addressed. And it would be best were it addressed explicitly.
Unfortunately, all parties responsible for the RFC are incommunicado!
> On 28-Nov-2002, the incomparable Joe Schaefer <joe+use...@sunstarsys.com> > wrote:
> >> The Cookie header specified in RFC 2965 (and earlier in RFC 2109) begins > >> with a cookie-version, and then with a semicolon- or comma-separated > >> representation of cookies.
> >> Hypothetically, two distinct headers (one for Version 0 cookies and > >> one for Version 1 cookies) might be sent. On the other hand, in > >> section 7.2 (Cookie Spoofing) of RFC 2965, a header is presented in > >> which the substring
> >> $Version="1";
> >> is placed in front of each of two cookies in a single header.
> > Yes, and note the ", " separating them.
> I did, but I'm not sure what significance you want me to impute to it.
RFC 2616, Section 4.2, last paragraph:
Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]. It MUST be possible to combine the multiple header fields into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field-value to the first, each separated by a comma. The order in which header fields with the same field-name are received is therefore significant to the interpretation of the combined field value, and thus a proxy MUST NOT change the order of these field values when a message is forwarded.
> The standard does not say that when a version declaration appears more > than one, a comma is to be used as a separator.
Right- the HTTP standard says that sending multiple "Cookie" headers MUST be equivalent to sending a single "Cookie" header with comma- separated "field-values".
[...]
> I also note, however, that the specifications in RFC 2965 are somewhat > informal. (For example, in 3.2.2, the specification of portlist is formally > incorrect.) Thus, I find it _plausible_ that the intention was that version > information may be provided more than once.
Agreed. However in light of 2616-4.2 above, I see the issue as being one of semantics. The BNF in 2965 doesn't permit multiple "$Version"s in a single header, AFAICT but there's no restriction on the number of "Cookie" headers a client may send to the server in a single request. Therefore the example in 7.2 must be interpreted as a "combination" ("folding" was a poor choice of words, I apologize) of two "Cookie" headers, since 2616 does not permit its interpretation as a single "header".
>> I did, but I'm not sure what significance you want me to impute to it.
> RFC 2616, Section 4.2, last paragraph:
> Multiple message-header fields with the same field-name MAY be > present in a message if and only if the entire field-value for that > header field is defined as a comma-separated list [i.e., #(values)]. It > MUST be possible to combine the multiple header fields into one > "field-name: field-value" pair, without changing the semantics of the > message, by appending each subsequent field-value to the first, each > separated by a comma. The order in which header fields with the same > field-name are received is therefore significant to the interpretation > of the combined field value, and thus a proxy MUST NOT change the order > of these field values when a message is forwarded.
>> The standard does not say that when a version declaration appears more >> than one, a comma is to be used as a separator.
> Right- the HTTP standard says that sending multiple "Cookie" headers > MUST be equivalent to sending a single "Cookie" header with comma- > separated "field-values".
Okay, I understand this, but it does not seem to resolve the problem.
>> I also note, however, that the specifications in RFC 2965 are somewhat >> informal. [...] Thus, I find it _plausible_ that the intention was that >> version information may be provided more than once.
> Agreed. However in light of 2616-4.2 above, I see the issue as > being one of semantics.
Yes, but I think that you here mean to claim that it is a framing problem, and unfortunately this is not a mere framing problem. The semantics (as they stand) do not seem subject to any resolution.
> The BNF in 2965 doesn't permit multiple > "$Version"s in a single header, AFAICT but there's no restriction on > the number of "Cookie" headers a client may send to the server in a > single request.
Well, let's look specifically at one sentence in the paragraph that you quoted:
It MUST be possible to combine the multiple header fields into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field-value to the first, each separated by a comma.
As I read this, headers may be combined into a single header, by concatenating them with intermediate commas, iff the result is an otherwise valid header. But two headers each conforming to the specification in RFC 2965 at 3.3.4 cannot be thus joined to form a header that conforms to 3.3.4.
Again, relaxation of the constraints of 3.3.4, so that more than one version specification may appear, may be the proper and intended resolution. Unfortunately, though I see the (problematic) example in 7.2 as suggesting a family of candidate solutions (which is why I drew attention to it), the purpose of that example was to address a different issue (spoofing), and the cookies are all of Version 1.
> [3] The only way to combine multiple headers into a single header while > conforming to the specification of the (client-sent) Cookie header > (3.3.4) is to strip away the Version-specification from all but the > first of the pre-combined headers (much as is the prefix "Cookie: ").
> The specification is
> cookie = "Cookie:" cookie-version 1*((";" | ",") cookie-value) > cookie-value = NAME "=" VALUE [";" path] [";" domain] [";" port] > cookie-version = "$Version" "=" value
Yes, exactly so. Please ignore my previous followup to your post, it's very late here and I see that you fully understand the issues. Right now I think the only reasonable conclusion about the sample "Cookie" header in 7.2 is that its incorrect, and should be 2 separate Cookie headers. But I also think that's a minor detail, and that you are raising a more significant point...
[...]
> The issue of what a client is to return (when cookies of different > versions match the server) needs to be addressed. And it would be > best were it addressed explicitly.
I'll think about this some more, after a bit of sleep and a reread of 2965. I think it'd help if you put forth an example client-server conversation, because 2965 does have *something* to say about client behavior wrt varying $Version numbers.
On 29-Nov-2002, the insufferable Daniel Kian Mc Kiernan wrote:
> (For example, in 3.2.2, the specification of portlist is formally > incorrect.)
I need to correct this parenthetical assertion; AFAIK, the specification of portlist is correct. It is the sepcification of the Version set-cookie-av which is incorrect; from the examples, one sees that it is supposed to be
4. Client visits osiris.ucsd.edu/foo/bar/index.htm . What should the client send?
One possibility would be to send three Cookie headers; another would be to send two, with the Version 0 cookies consolidated. (This latter approach would violate the _spirit_ but not _letter_ of the rule on ordering by path-specificity in 3.3.4.) RFC 2965 presents _no_ explicit consideration of multiple Cookie headers being used at a single pass (see previous parenthetical note), which makes me suspicious of the legitimacy of such an approach.
Version 0 cookies could be translated into Version 1 cookies. But this would amount to lying to a server that might correlate Version with more than merely the structure of cookie-avs.
On 29-Nov-2002, the insufferable Daniel Kian Mc Kiernan wrote:
> (For example, in 3.2.2, the specification of portlist is formally > incorrect.)
I need to correct this parenthetical assertion; AFAIK, the specification of portlist is correct. It is the sepcification of the Version set-cookie-av which is incorrect; from the examples, one sees that it is supposed to be
Therein, I found a different e.mail address for Kristol, I have therefore made another attempt to contact him. I will of course share anything that I learn.
weber.ucsd.edu is not implementing 2965 (Set-Cookie isn't a 2965 header). Presumably the client is implementing both 2965 and Netscape's standard, so it stores this as a Netscape ($Version=0) cookie.
> 2. Client visits lusin.ucsd.edu/~acgamst/foo/bar/ . Server sends
That is a 2965 cookie. Assuming the client enforces 3.3.2, it should reject that cookie (AAUI the $Path above is not a "prefix" of the request-URI). Since I don't think this technicality is relevant to the topic of discussion, lets say the original URI was
lusin.ucsd.edu/foo/bar/
so the client unequivocally stores it as a $Version=1 2956 cookie.
> 3. Client visits ieng9.ucsd.edu/~cs131f/ . Server sends
Again, a Netscape cookie. The Netscape spec imposes no relation on the request-URI and the cookie path, so the client stores this straightaway as a Netscape cookie.
> 4. Client visits osiris.ucsd.edu/foo/bar/index.htm . What should the > client send?
> One possibility would be to send three Cookie headers; > another would be to send two, with the Version 0 cookies > consolidated. (This latter approach would violate the _spirit_ but not > _letter_ of the rule on ordering by path-specificity in 3.3.4.)
My reading of 9.1 is different. In particular, I see it this way:
A user agent that supports both this specification and Netscape-style cookies SHOULD send a Cookie request header that follows the older Netscape specification if it received the cookie in a Set-Cookie ... ^^^ a
(where the cookies in question are the ones relevant to the URI, applying both specs independently).
My interpretation [1] suggests that the client SHOULD send
1) downgrades [2] the 2956 cookie to a Netscape cookie, 2) follows the Netscape standard in constructing a Cookie header, 3) Notifies the server that it supports 2956 via the Cookie2 header.
Basically, interoperability trumps security here.
> RFC 2965 presents _no_ explicit consideration of multiple Cookie > headers being used at a single pass (see previous parenthetical note), > which makes me suspicious of the legitimacy of such an approach.
Agreed. Now that I'm awake :-), I don't believe that it is ever valid for a client to send multiple Cookie headers within a single request.
[1] - I've looked at a half-dozen clients that ostensibly support both specs, and not one of them agrees with my interpretation.
[2] - To my knowledge, "downgrading" a 2956 cookie to a NS cookie isn't described anywhere in any spec, but my intent should be clear that this is only done for the purposes of serializing the cookie data and constructing the Cookie header. It amounts to simply not sending any of a 2956 cookie's attributes back to the server, and following the Netscape spec for path ordering.
On 30-Nov-2002, the incomparable Joe Schaefer wrote:
> My reading of 9.1 is different. In particular, I see it this way:
> A user agent that supports both this specification and Netscape-style > cookies SHOULD send a Cookie request header that follows the older > Netscape specification if it received the cookie in a Set-Cookie ... > ^^^ > a <snip> > IOW, the user agent
> 1) downgrades [2] the 2956 cookie to a Netscape cookie, > 2) follows the Netscape standard in constructing a Cookie header, > 3) Notifies the server that it supports 2956 via the Cookie2 header.
But let's say that the client already holds a Version 1 (2965) cookie from the fourth machine. (Alternately, make the fourth visit a return to the second machine.) That cookie would then be returned as a Version 0 (Netscape) cookie. It seems to me that (because RFC 2965 did not explicitly declare this or any policy) the programmers and coders of the server will presume that their own cookie will be returned to them -- if at all -- as a Version 1 cookie. Operationally, a domain- and path-matching Version 0 cookie could "break" server code widely thought to be compliant with RFC 2965.
(Off the top of my head, it also seems that translating Version 1 cookies to Version 0 cookies could undermine some of the social objectives of the the new standard. It would be unfortunate to give one site the power to effect another in such a way.)
> [1] - I've looked at a half-dozen clients that ostensibly support > both specs, and not one of them agrees with my interpretation.
Hahahahaha!!!
Well, one of those clients might be doing the right thing; but, if so, it is perhaps only by chance co-incidence. A programmer doing his or her job correctly would have had doubts, which you and I should find represented in some form of public discourse or announcement!
> On 30-Nov-2002, the incomparable Joe Schaefer wrote:
> > My reading of 9.1 is different. In particular, I see it this way:
> > A user agent that supports both this specification and Netscape-style > > cookies SHOULD send a Cookie request header that follows the older > > Netscape specification if it received the cookie in a Set-Cookie ... > > ^^^ > > a > <snip> > > IOW, the user agent
> > 1) downgrades [2] the 2956 cookie to a Netscape cookie, > > 2) follows the Netscape standard in constructing a Cookie header, > > 3) Notifies the server that it supports 2956 via the Cookie2 header.
> But let's say that the client already holds a Version 1 (2965) cookie from > the fourth machine. (Alternately, make the fourth visit a return to the > second machine.) That cookie would then be returned as a Version 0 > (Netscape) cookie. It seems to me that (because RFC 2965 did not explicitly > declare this or any policy) the programmers and coders of the server will > presume that their own cookie will be returned to them -- if at all -- as a > Version 1 cookie. Operationally, a domain- and path-matching Version 0 > cookie could "break" server code widely thought to be compliant with RFC > 2965.
At this point in time, I'd consider it somewhat irresponsible for server software to support 2965 to the exclusion of the Netscape spec. Further, I'd rather postpone server-side expectations/discussions a bit, since the server has no right to expect the client to do anything with a cookie. As far as the server is concerned, the HTTP transaction is over.
Right now, I'm interested in learning what a user agent's "current best practices" might/should be under the circumstances you have described. I certainly don't believe that my proposed, theoretical solution is best (or in the spirit of 2956), and it's certainly not what browser implementers have done.
On 30-Nov-2002, the incomparable Joe Schaefer wrote:
> At this point in time, I'd consider it somewhat irresponsible for > server software to support 2965 to the exclusion of the Netscape spec.
I agree entirely, but consider a server that send both a Set-Cookie and a Set-Cookie2 header, with one or more cookies unique to the Set-Cookie2 header. I suspect that a programmer doing such a thing would not anticipate those unique cookies coming back as Version 0 cookies.
> Further, I'd rather postpone server-side expectations/discussions a bit, > since the server has no right to expect the client to do anything with > a cookie. As far as the server is concerned, the HTTP transaction is > over.
I'm willing to postpone such discussion (but I think that while a server has no right to expect a client to return a cookie, it _might_ have a right to expect that any return have certain properties).
> Right now, I'm interested in learning what a user agent's "current > best practices" might/should be under the circumstances you have > described.
I agree (though I think that best client practice must be informed both by best server practice and by actual server practice, as vice versa).
I have in fact received (and just replied to) a message from David Kristol. He believes that RFC 2616 permits Cookie headers to be combined into one as in the example of RFC 2965 section 7.2, and that section 9.1 implies that this is the course that one should take. (I have argued that thus combining Cookie headers violates RFC 2616, and that 9.1 does not have such implication.)
> I certainly don't believe that my proposed, theoretical > solution is best (or in the spirit of 2965), and it's certainly not > what browser implementers have done.
On 30-Nov-2002, the insufferable Daniel Kian Mc Kiernan wrote:
> I agree entirely, but consider a server that send both a Set-Cookie and a > Set-Cookie2 header, with one or more cookies unique to the Set-Cookie2 > header. I suspect that a programmer doing such a thing would not > anticipate those unique cookies coming back as Version 0 cookies.
(Lest there be some third-party confusing, let me note that I here have in mind a situation where some _other_ server has also sent a relevant Set-Cookie header.)
"Daniel Kian Mc Kiernan" <Mc-Kier...@bogus-subdomain.worldnet.att.net> writes:
[...]
> I have in fact received (and just replied to) a message from David > Kristol. He believes that RFC 2616 permits Cookie headers to be > combined into one as in the example of RFC 2965 section 7.2, and that > section 9.1 implies that this is the course that one should take. (I > have argued that thus combining Cookie headers violates RFC 2616, and > that 9.1 does not have such implication.)
Your argument certainly has merit.
[...]
> What have browser implementers done?
The short story: clients typically treat $Version as a per-cookie attribute, and construct the "Cookie" header by concatenating each individual cookie according to its original type: Netscape, 2109 (?!?!) or 2965. (The long story isn't ready, and won't be for some time, unless someone else wants to write about it :-).
In my irrelevant opinion, this is an undesirable outcome. I'd rather have seen the Cookie2 header [1] omitted from 2965, and Section 9.1 replaced with language encouraging user agents to promote all outgoing cookies to $Version=1 (with rigid compliance to 2965's Cookie BNF). Specifically, I view the $Version component of the Cookie header to be an in-band means of telling the server which Cookie spec the user agent understands best. I do not view it as a per-cookie attribute.
In contrast to my earlier suggestion, I think the "current best practices" should choose "security over interoperability" and take some reasonable liberties with the Netscape spec. After all, that was the intended result of 2109 (in particular Section 10.1.1 of RFC 2109).
The punch-line is that David Kristol now reports that multiple Cookie headers are permitted in a single pass. (I have sent back a note on the implications for ordering by path-specificity.)
On 30-Nov-2002, the incomparable Joe Schaefer wrote:
>> I have in fact received (and just replied to) a message from David >> Kristol. He believes that RFC 2616 permits Cookie headers to be >> combined into one as in the example of RFC 2965 section 7.2, and that >> section 9.1 implies that this is the course that one should take. (I >> have argued that thus combining Cookie headers violates RFC 2616, and >> that 9.1 does not have such implication.)
> Your argument certainly has merit.
Mr Kristol accepts the argument, and thus now declares the example at 7.2 to be flawed.
> The short story: clients typically treat $Version as a per-cookie > attribute, and construct the "Cookie" header by concatenating each > individual cookie according to its original type: Netscape, 2109 (?!?!) > or 2965. (The long story isn't ready, and won't be for some time, > unless someone else wants to write about it :-).
> In my irrelevant opinion, this is an undesirable outcome.
I agree.
> I'd rather > have seen the Cookie2 header [1] omitted from 2965, and Section 9.1 > replaced with language encouraging user agents to promote all outgoing > cookies to $Version=1 (with rigid compliance to 2965's Cookie BNF).
I'd not considered omission of the Cookie2 header.
> In contrast to my earlier suggestion, I think the "current best > practices" should choose "security over interoperability" and take > some reasonable liberties with the Netscape spec.
I agree; the interoperability that most concerned me was that specifically designed to promote secuirty.
I've received permission from Mr Kristol to post his e.mail to me. I will now begin doing so.
-------- Original Message -------- Date: Sat, 30 Nov 2002 12:05:40 -0500 From: Dave Kristol Subject: Re: RFC 2965 To: "Mc Kiernan, Daniel Kian"
Hi. I saw your posting in comp.infosystems.www.servers.unix, but I hadn't had a chance to respond.
> I am having difficulty inferring what a client is supposed to transmit > in its Cookie header when it has multiple cookies that domain-, port-, > and path-match, but with at least one such cookie being Version 0, and > at least one cookie being Version 1.
Well, for a start, note RFC 2965, sect. 9.1:
Existing cookie implementations, based on the Netscape specification, use the Set-Cookie (not Set-Cookie2) header. User agents that receive in the same response both a Set-Cookie and Set-Cookie2 response header for the same cookie MUST discard the Set-Cookie information and use only the Set-Cookie2 information. Furthermore, a user agent MUST assume, if it received a Set-Cookie2 response header, that the sending server complies with this document and will understand Cookie request headers that also follow this specification.
So (as I think you inferred), you would send (conceptually) more than one Cookie header to the server.
> In Section 7.2 (Cookie Spoofing), there is an example header
> which suggests that the Version datum might accompany each cookie, or be > used as a toggle, but this example would at least seem to conflict with > the header specification of 3.3.4.
Well, in fact, there's no conflict, although there *is* a subtlety. RFC 2965 defines the content of a Cookie header, which represents one cookie. RFC 2616 (HTTP/1.1) defines rules for combining (I called it "folding", which apparently caused you some trouble) more than one header of the same name. So the example in 7.2 is what you would get if you combined these two Cookie headers:
In another message in your thread, you said: > I also note, however, that the specifications in RFC 2965 are somewhat > informal. (For example, in 3.2.2, the specification of portlist is > formally incorrect.)
Can you explain why you think that there is a problem with portlist?
This message is reproduced with the permission of its author.
-------- Original Message -------- Date: Sat, 30 Nov 2002 12:05:40 -0500 From: Dave Kristol Subject: Re: RFC 2965 To: "Mc Kiernan, Daniel Kian"
>> Hi. I saw your posting in comp.infosystems.www.servers.unix, but I >> hadn't had a chance to respond.
> TNX much for responding. I would like your permission to post your > remarks in Usenet, unless you are going to provide equivalent or > preempting remarks therein.
You may post my remarks.
BTW, I have left Bell Labs (you probably figured that out already), and I haven't really dealt with cookie issues for 1 1/2 years, except to answer the occasional question like yours. So my logic and answers could be rusty.
>>> I am having difficulty inferring what a client is supposed to >>> transmit in its Cookie header when it has multiple cookies that >>> domain-, port-, and path-match, but with at least one such cookie >>> being Version 0, and at least one cookie being Version 1.
>> Well, for a start, note RFC 2965, sect. 9.1:
>> Existing cookie implementations, based on the Netscape specification,
> <snip>
>> specification.
> Unfortunately, that passage doesn't really address the question. The > domain- and path-matching cookies may come from different sites than > that to which the client is "now" connected. And the presumption that > the server understands Version 1 cookies isn't the same as the > presumption that it should be sent Version 1 cookies. (Mr Schaefer > indeed concluded that all Version 1 cookies should be translated to > Version 0 when any Version 0 cookie is to be sent. I raised some > concerns about this interpretation, but those concerns don't seem > logically overwhelming.)
Our assumption was indeed that you send V1 cookies to a server that understands them. So maybe you need to give me an example of what you have in mind.
Hmmm. Here's one different case. Suppose you have V1 cookies from a.foo.com and b.foo.com, V0 cookies from c.foo.com, all of which say Domain=".foo.com", and you're sending a request to, let's say, c.foo.com. In that case you would want to send all the cookies to c.foo.com (for Domain=".foo.com").
I think you're right that this does not work very well at all. Perhaps we (the HTTP state management sub-group) were a bit too optimistic that web sites would do reasonable things, like switch to using V1 cookies for all their servers. Therefore, there was never the intent to translate V1 cookies and then send them to V0 servers. IMO, the only correct behavior for a client in the above example is to send just the V0 cookie(s) to c.foo.com.
You've probably noticed that RFC 2965 (and 2109 before) avoided as much as possible discussing Netscape's specification. The point of the RFCs was to supercede NS cookies, though that effort may have failed. (For more details, see "HTTP Cookies: Standards, Privacy, and Politics", <http://arXiv.org/abs/cs.SE/0105018>, May 9, 2001, or the version in ACM Transactions on Internet Technology, Volume 1, #2, November, 2001, pp.151-198.) We did not address the possibility of sending V1 cookies to V0 servers.
>>> which suggests that the Version datum might accompany each cookie, or >>> be used as a toggle, but this example would at least seem to conflict >>> with the header specification of 3.3.4.
>> Well, in fact, there's no conflict, although there *is* a subtlety. >> RFC 2965 defines the content of a Cookie header, which represents one >> cookie. RFC 2616 (HTTP/1.1) defines rules for combining (I called it >> "folding", which apparently caused you some trouble) more than one >> header of the same name. So the example in 7.2 is what you would get >> if you combined these two Cookie headers:
> But here's the relevant passage of RFC 2616 (in 4.2):
> Multiple message-header fields with the same field-name MAY > be present in a message if and only if the entire field- > value for that header field is defined as a comma-separated > list [i.e., #(values)]. It MUST be possible to combine the > multiple header fields into one "field-name: field-value" > pair, without changing the semantics of the message, by > appending each subsequent field-value to the first, each > separated by a comma. The order in which header fields with > the same field-name are received is therefore significant to > the interpretation of the combined field value, and thus a > proxy MUST NOT change the order of these field values when a > message is forwarded.
That's a good point, and, as you point out, the syntax in RFC 2965 does not allow for that combining in Cookie. So I have to agree with you, which renders the 7.2 example bogus.
> Elsewhere in the Usenet thread, I've drawn attention to the second > sentence amongst those rules:
> It MUST be possible to combine the multiple header fields > into one "field-name: field-value" pair, without changing the > semantics of the message, by appending each subsequent field- > value to the first, each separated by a comma.
> As I read this, headers may be combined into a single header, by > concatenating them with intermediate commas, iff the result is an > otherwise valid header. But two headers each conforming to the > specification in RFC 2965 at 3.3.4 cannot be thus joined to form a > header that conforms to 3.3.4.
True.
> Further, as I also note, if one can _baldly_ send more than one Cookie > header, then it becomes possible to violate the _spirit_ of the > path-specificity ordering rule without violating the the _letter_ of > that rule. If the example at 7.2 is _conceptually_ two headers, then an > otherwise disallowed ordering might be permitted.
An example of what you mean might be helpful, and, yes, one can send more than one Cookie header.
We had discussions about the combinatorics of path- and domain- matching and basically threw up our hands, because it would be nearly impossible to state a reasonable set of rules for the ordering of cookies. Instead we hoped (admittedly, not a great way to write a standard) that implementers would be reasonable in their use of cookies. Generally that would mean that most cookies that are meant to be sent to the same (set of) sites would share the same Domain= and Path= values, and we were assured that that was usually the case by two vendors.
> Were the specification at 3.3.4 amended to read
> cookie = "Cookie:" cookie-list *("," cookie-list) > cookie-list = cookie-version 1*(";" cookie-value) > cookie-version = "$Version" "=" value > cookie-value = NAME "=" VALUE [";" path] [";" domain] [";" port] > NAME = attr > VALUE = value > path = "$Path" "=" value > domain = "$Domain" "=" value > port = "$Port" [ "=" <"> 1#(1*DIGIT) <"> ]
> this would provide a resolution. (I still believe that it would be > desirable to provide explicit guidance for the case of differing > Versions.)
To be honest, I no longer recall why we didn't go that route. It would have helped to distinguish different cookie versions (if it ever came to that), and it would help resolve the syntactic problem with combining cookies. I have, in the back of my head, the notion that $Version would apply to all cookies in the (RFC 2965) cookie token until another $Version is seen, but perhaps I'm confusing that with Set-Cookie2.
>>> I also note, however, that the specifications in RFC 2965 are somewhat >>> informal. (For example, in 3.2.2, the specification of portlist is >>> formally incorrect.)
>> Can you explain why you think that there is a problem with portlist?
> Sorry, I was tired when I made that claim. I posted a correct at about > 3 AM this morning. What I was incompetently remembering was the problem > with the Version set-cookie-av. Your examples and other remarks make it > plain that you wanted
You're right about intent. If you look at 3.2.2, under the discussion of semantics, there's Version=value, and I then state that the value is a decimal integer. The intent was to allow (all) values to be quotable, but I botched the syntax on this one.
> BTW, it seems that you might also have written
> | "Max-Age" "=" (1*DIGIT | <"> 1*DIGIT <">)
The same idea applies to Max-Age as to Version, but this time I put the specificity about the value in the semantic description.
This message is reproduced with the permission of its author.
-------- Original Message -------- Date: Sat, 30 Nov 2002 16:35:46 -0500 From: Dave Kristol Subject: Re: RFC 2965 To: "Mc Kiernan, Daniel Kian"
>> Hi. I saw your posting in comp.infosystems.www.servers.unix, but I >> hadn't had a chance to respond.
> TNX much for responding. I would like your permission to post your > remarks in Usenet, unless you are going to provide equivalent or > preempting remarks therein.
You may post my remarks.
BTW, I have left Bell Labs (you probably figured that out already), and I haven't really dealt with cookie issues for 1 1/2 years, except to answer the occasional question like yours. So my logic and answers could be rusty.
>>> I am having difficulty inferring what a client is supposed to >>> transmit in its Cookie header when it has multiple cookies that >>> domain-, port-, and path-match, but with at least one such cookie >>> being Version 0, and at least one cookie being Version 1.
>> Well, for a start, note RFC 2965, sect. 9.1:
>> Existing cookie implementations, based on the Netscape specification,
> <snip>
>> specification.
> Unfortunately, that passage doesn't really address the question. The > domain- and path-matching cookies may come from different sites than > that to which the client is "now" connected. And the presumption that > the server understands Version 1 cookies isn't the same as the > presumption that it should be sent Version 1 cookies. (Mr Schaefer > indeed concluded that all Version 1 cookies should be translated to > Version 0 when any Version 0 cookie is to be sent. I raised some > concerns about this interpretation, but those concerns don't seem > logically overwhelming.)
Our assumption was indeed that you send V1 cookies to a server that understands them. So maybe you need to give me an example of what you have in mind.
Hmmm. Here's one different case. Suppose you have V1 cookies from a.foo.com and b.foo.com, V0 cookies from c.foo.com, all of which say Domain=".foo.com", and you're sending a request to, let's say, c.foo.com. In that case you would want to send all the cookies to c.foo.com (for Domain=".foo.com").
I think you're right that this does not work very well at all. Perhaps we (the HTTP state management sub-group) were a bit too optimistic that web sites would do reasonable things, like switch to using V1 cookies for all their servers. Therefore, there was never the intent to translate V1 cookies and then send them to V0 servers. IMO, the only correct behavior for a client in the above example is to send just the V0 cookie(s) to c.foo.com.
You've probably noticed that RFC 2965 (and 2109 before) avoided as much as possible discussing Netscape's specification. The point of the RFCs was to supercede NS cookies, though that effort may have failed. (For more details, see "HTTP Cookies: Standards, Privacy, and Politics", <http://arXiv.org/abs/cs.SE/0105018>, May 9, 2001, or the version in ACM Transactions on Internet Technology, Volume 1, #2, November, 2001, pp.151-198.) We did not address the possibility of sending V1 cookies to V0 servers.
>>> which suggests that the Version datum might accompany each cookie, or >>> be used as a toggle, but this example would at least seem to conflict >>> with the header specification of 3.3.4.
>> Well, in fact, there's no conflict, although there *is* a subtlety. >> RFC 2965 defines the content of a Cookie header, which represents one >> cookie. RFC 2616 (HTTP/1.1) defines rules for combining (I called it >> "folding", which apparently caused you some trouble) more than one >> header of the same name. So the example in 7.2 is what you would get >> if you combined these two Cookie headers:
> But here's the relevant passage of RFC 2616 (in 4.2):
> Multiple message-header fields with the same field-name MAY > be present in a message if and only if the entire field- > value for that header field is defined as a comma-separated > list [i.e., #(values)]. It MUST be possible to combine the > multiple header fields into one "field-name: field-value" > pair, without changing the semantics of the message, by > appending each subsequent field-value to the first, each > separated by a comma. The order in which header fields with > the same field-name are received is therefore significant to > the interpretation of the combined field value, and thus a > proxy MUST NOT change the order of these field values when a > message is forwarded.
That's a good point, and, as you point out, the syntax in RFC 2965 does not allow for that combining in Cookie. So I have to agree with you, which renders the 7.2 example bogus.
> Elsewhere in the Usenet thread, I've drawn attention to the second > sentence amongst those rules:
> It MUST be possible to combine the multiple header fields > into one "field-name: field-value" pair, without changing the > semantics of the message, by appending each subsequent field- > value to the first, each separated by a comma.
> As I read this, headers may be combined into a single header, by > concatenating them with intermediate commas, iff the result is an > otherwise valid header. But two headers each conforming to the > specification in RFC 2965 at 3.3.4 cannot be thus joined to form a > header that conforms to 3.3.4.
True.
> Further, as I also note, if one can _baldly_ send more than one Cookie > header, then it becomes possible to violate the _spirit_ of the > path-specificity ordering rule without violating the the _letter_ of > that rule. If the example at 7.2 is _conceptually_ two headers, then an > otherwise disallowed ordering might be permitted.
An example of what you mean might be helpful, and, yes, one can send more than one Cookie header.
We had discussions about the combinatorics of path- and domain- matching and basically threw up our hands, because it would be nearly impossible to state a reasonable set of rules for the ordering of cookies. Instead we hoped (admittedly, not a great way to write a standard) that implementers would be reasonable in their use of cookies. Generally that would mean that most cookies that are meant to be sent to the same (set of) sites would share the same Domain= and Path= values, and we were assured that that was usually the case by two vendors.
> Were the specification at 3.3.4 amended to read
> cookie = "Cookie:" cookie-list *("," cookie-list) > cookie-list = cookie-version 1*(";" cookie-value) > cookie-version = "$Version" "=" value > cookie-value = NAME "=" VALUE [";" path] [";" domain] [";" port] > NAME = attr > VALUE = value > path = "$Path" "=" value > domain = "$Domain" "=" value > port = "$Port" [ "=" <"> 1#(1*DIGIT) <"> ]
> this would provide a resolution. (I still believe that it would be > desirable to provide explicit guidance for the case of differing > Versions.)
To be honest, I no longer recall why we didn't go that route. It would have helped to distinguish different cookie versions (if it ever came to that), and it would help resolve the syntactic problem with combining cookies. I have, in the back of my head, the notion that $Version would apply to all cookies in the (RFC 2965) cookie token until another $Version is seen, but perhaps I'm confusing that with Set-Cookie2.
>>> I also note, however, that the specifications in RFC 2965 are somewhat >>> informal. (For example, in 3.2.2, the specification of portlist is >>> formally incorrect.)
>> Can you explain why you think that there is a problem with portlist?
> Sorry, I was tired when I made that claim. I posted a correct at about > 3 AM this morning. What I was incompetently remembering was the problem > with the Version set-cookie-av. Your examples and other remarks make it > plain that you wanted
You're right about intent. If you look at 3.2.2, under the discussion of semantics, there's Version=value, and I then state that the value is a decimal integer. The intent was to allow (all) values to be quotable, but I botched the syntax on this one.
> BTW, it seems that you might also have written
> | "Max-Age" "=" (1*DIGIT | <"> 1*DIGIT <">)
The same idea applies to Max-Age as to Version, but this time I put the specificity about the value in the semantic description.