Subject: [http-state] The Domain attribute (was Re: I-D Action:draft-ietf-httpstate-cookie-20.txt)

From: Adam Barth <[email-masked]>
Date: Thu, 6 Jan 2011 12:50:24 -0800

On Thu, Jan 6, 2011 at 7:57 AM, Paul E. Jones <[email-masked]> wrote:
> Adam,
>
> In the RFC 2109, the "domain" attribute is optional.  Specifically, it says:
>
>   Domain=domain
>      Optional.  The Domain attribute specifies the domain for which the
>      cookie is valid.  An explicitly specified domain must always start
>      with a dot.
>
>  It also defined a default:
>   Domain Defaults to the request-host.  (Note that there is no dot at
>          the beginning of request-host.)

Right.

> I found this in the -20 draft:
>
> 4.1.2.3:
>   If the server omits the Domain attribute, the user
>   agent will return the cookie only to the origin server.
>
>      WARNING: Some existing user agents treat an absent Domain
>      attribute as if the Domain attribute were present and contained
>      the current host name.  For example, if example.com returns a Set-
>      Cookie header without a Domain attribute, these user agents will
>      erroneously send the cookie to www.example.com as well.
>
> If I received a cookie without a domain from test.example.com, I would
> assume the cookie's domain is "test.example.com".  The wording above
> confuses me a little, as I would bind the cookie to the host I accessed.
> The first sentence in the WARNING seems like what I should do, but the
> example presented is not the origin server or the "current host name".  I
> agree that it would be an error for a browser to assume a larger domain
> scope than just the single host being accessed.  But, I would think that
> absence of or an empty string for "Domain" would be bound only to the server
> being accessed.  I believe that is the intent, as stated in other sections,
> but the warning text seems to suggest otherwise when I read it.

Right, the issue is that some browsers forget to set the host-only
flag on the cookie if you omit the Domain attribute.  That causes the
cookie to be returned to the origin server as well as all subdomains
of the origin server's host name.

> In Section 5.2.3, this text appears:
>   If the attribute-value is empty, the behavior is undefined.  However,
>   user agent SHOULD ignore the cookie-av entirely.
>
> Why would the behavior be undefined?  Why would these not be treated
> identically?
> Set-Cookie: mycookie=myvalue; path=/
> Set-Cookie: mycookie=myvalue; path=/; domain=

It's undefined because different implementations do different things
and I didn't have the energy or the inclination to beat them up on
this point.  They should do what the document suggests, but it's not
the end of the world fi they don't.

> Why isn't an empty string a valid value?  I ask, because we assign an empty
> value internally.  In 5.3, paragraph 4, we have:
>
>   4.   If the cookie-attribute-list contains an attribute with an
>        attribute-name of "Domain":
>
>           Let the domain-attribute be the attribute-value of the last
>           attribute in the cookie-attribute-list with an attribute-name
>           of "Domain".
>
>        Otherwise:
>
>           Let the domain-attribute be the empty string.
>
> So, this does suggest "domain=" would be the same as absence of the domain
> parameter, no?

Well, the complexity actually arises when the server provides multiple
Domain attributes, some of which are the empty string.  Which one
actually controls the result varies.

The rules are written such that if you follow them, you get reasonable
behavior that matches practice.  There's also some wiggle room to in
this extreme corner case (multiple attributes, one of which is the
empty string).  We could nail that issue down, but it didn't seem
worth the hassle.

> Paragraph 6 then explains that in such cases, the domain is
> assigned to "the canonicalized request-host", which is consistent.
>
> So, any reason why the Domain a/v syntax isn't this?
> domain-value      = <subdomain> | ""

Just because it's nonsense semantically and an interoperability
sandtrap.  If you'd like to use the empty string, just omit the Domain
attribute instead.  Your life and everyone else's life will be happier
for it.

Adam

>> -----Original Message-----
>> From: [email-masked] [mailto:[email-masked]]
>> On Behalf Of [email-masked]
>> Sent: Sunday, December 19, 2010 2:00 PM
>> To: [email-masked]
>> Cc: [email-masked]
>> Subject: [http-state] I-D Action:draft-ietf-httpstate-cookie-20.txt
>>
>> A New Internet-Draft is available from the on-line Internet-Drafts
>> directories.
>> This draft is a work item of the HTTP State Management Mechanism Working
>> Group of the IETF.
>>
>>
>>       Title           : HTTP State Management Mechanism
>>       Author(s)       : A. Barth
>>       Filename        : draft-ietf-httpstate-cookie-20.txt
>>       Pages           : 44
>>       Date            : 2010-12-19
>>
>> This document defines the HTTP Cookie and Set-Cookie header fields.
>> These header fields can be used by HTTP servers to store state (called
>> cookies) at HTTP user agents, letting the servers maintain a stateful
>> session over the mostly stateless HTTP protocol.  Although cookies have
>> many historical infelicities that degrade their security and privacy,
>> the Cookie and Set-Cookie header fields are widely used on the
>> Internet.Editorial Note (To be removed by RFC Editor)
>>
>> If you have suggestions for improving this document, please send email
>> to <mailto:[email-masked]>.  Suggestions with test cases are
>> especially appreciated.  Further Working Group information is available
>> from <https://tools.ietf.org/wg/httpstate/>.
>>
>> A URL for this Internet-Draft is:
>> http://www.ietf.org/internet-drafts/draft-ietf-httpstate-cookie-20.txt
>>
>> Internet-Drafts are also available by anonymous FTP at:
>> ftp://ftp.ietf.org/internet-drafts/
>>
>> Below is the data which will enable a MIME compliant mail reader
>> implementation to automatically retrieve the ASCII version of the
>> Internet-Draft.
>
>

---

From: "Paul E. Jones" <[email-masked]>
Date: Thu, 6 Jan 2011 17:22:19 -0500

Adam,

Thanks for the clarification.  Now I understand that many of the decisions
made were based on real-world implementations and a desire to make things no
worse than they already are. ;-)

Perhaps the one point of disagreement is whether this syntax is valid:
domain-value      = <subdomain> | ""

I agree that one could omit the Domain attribute and probably should, but
the above syntax is consistent with text that talks about an "empty string".
We have to give that treatment, since an empty string actually means
something.

The empty string is also used in this example:
Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT

For this reason, this might be another area where we need to consider a
syntax change:
cookie-pair       = cookie-name "=" cookie-value
cookie-name       = token
cookie-value      = token | ""
                         ^^^^^

These are the only examples I can think of where I've seen attributes that
do not have assigned values (i.e., have an empty strings) on the wire, each
done so deliberately and with a particular meaning.

In any case, I don't have a strong preference and if the group wants to
change the syntax.  That's OK.  It just seems allowing an empty string for
"Domain" is more consistent with the text than not.

Paul

> From: Adam Barth [mailto:[email-masked]]
> Sent: Thursday, January 06, 2011 3:50 PM
> To: Paul E. Jones
> Cc: [email-masked]
> Subject: The Domain attribute (was Re: [http-state] I-D Action:draft-
> ietf-httpstate-cookie-20.txt)
> 
> > example presented is not the origin server or the "current host
> name".
> > I agree that it would be an error for a browser to assume a larger
> > domain scope than just the single host being accessed.  But, I would
> > think that absence of or an empty string for "Domain" would be bound
> > only to the server being accessed.  I believe that is the intent, as
> > stated in other sections, but the warning text seems to suggest
> otherwise when I read it.
> 
> Right, the issue is that some browsers forget to set the host-only flag
> on the cookie if you omit the Domain attribute.  That causes the cookie
> to be returned to the origin server as well as all subdomains of the
> origin server's host name.
> 
> It's undefined because different implementations do different things and
> I didn't have the energy or the inclination to beat them up on this
> point.  They should do what the document suggests, but it's not the end
> of the world fi they don't.
> 
> > Why isn't an empty string a valid value?  I ask, because we assign an
> > empty value internally.  In 5.3, paragraph 4, we have:
> >
> > So, this does suggest "domain=" would be the same as absence of the
> > domain parameter, no?
> 
> this extreme corner case (multiple attributes, one of which is the empty
> string).  We could nail that issue down, but it didn't seem worth the
> hassle.
> 
> > Paragraph 6 then explains that in such cases, the domain is  assigned
> >to "the canonicalized request-host", which is consistent.
> >
> >> This draft is a work item of the HTTP State Management Mechanism
> >> Working Group of the IETF.
> >>
> >>
> >> session over the mostly stateless HTTP protocol.  Although cookies
> >> have many historical infelicities that degrade their security and
> >> privacy, the Cookie and Set-Cookie header fields are widely used on
> >> the Internet.Editorial Note (To be removed by RFC Editor)
> >>
> >> If you have suggestions for improving this document, please send
> >> email to <mailto:[email-masked]>.  Suggestions with test cases
> >> are especially appreciated.  Further Working Group information is
> >> available from <https://tools.ietf.org/wg/httpstate/>.
> >>

---

From: Adam Barth <[email-masked]>
Date: Thu, 6 Jan 2011 15:18:20 -0800

> We have to give that treatment, since an empty string actually means

We don't have to do anything.  In particular, not every piece of
syntax that semantically meaningful need be valid.

> Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT

Why is that?  The "lang" attribute has not been defined, so the valid
values for the lang attribute certainly haven't been defined.

> cookie-value      = token | ""

I would not recommend that servers send empty attribute values.
That's just asking for interoperability problems.

> "Domain" is more consistent with the text than not.

More consistent with what text?  The text in the User Agent
Requirements section is for user agents and not for servers.  You're
talking about what's useful for syntax for servers to generate.  It's
not useful for servers to generate empty Domain attributes.  Instead
of generating an empty Domain attribute, they ought to simply omit the
Domain attribute.

Adam

---

From: "Paul E. Jones" <[email-masked]>
Date: Thu, 6 Jan 2011 21:13:07 -0500

Adam,

> > For this reason, this might be another area where we need to consider
> > a syntax change:
> > cookie-pair       = cookie-name "=" cookie-value cookie-name       =
> > token cookie-value      = token | ""
> >                         ^^^^^
> 

But, "lang" is sent in the above example as an empty string.  Thus, this
should be the definition of "cookie-value":
cookie-value      = token | ""

As the text is current written, I think this is illegal:
Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT

> > In any case, I don't have a strong preference and if the group wants
> > to change the syntax.  That's OK.  It just seems allowing an empty
> > string for "Domain" is more consistent with the text than not.
> 
> More consistent with what text?  The text in the User Agent Requirements
> section is for user agents and not for servers.  You're talking about
> what's useful for syntax for servers to generate.  It's not useful for
> servers to generate empty Domain attributes.  Instead of generating an
> empty Domain attribute, they ought to simply omit the Domain attribute.

OK, that's a good argument. :-)

Paul

---

From: Adam Barth <[email-masked]>
Date: Thu, 6 Jan 2011 18:18:13 -0800

> Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT

Oh, sorry, got confused.  Empty strings should be allowed for
cooke-values but not for attribute-values.

Adam