You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-dev@httpd.apache.org by Clinton Gormley <cl...@traveljury.com> on 2009/02/14 14:21:51 UTC

Cookie parsing errors: conflicting information, expected token not present

Hiya

There has been some discussion about cookie parsing errors with
libapreq2 on the modperl list, and Joe Schafer said:

	What version of apreq was this?  And did you report it to the 	
	apreq-dev@ mailing list?

While I have previously reported the errors I see to the modperl list, I
thought I'd send them here as well.

This is in apache 2.2.4 with libapreq2-2.08, on linux x86_64.

The code I use to parse the cookies is as follows:

------------------------------------------------------------------------
        my $req = APR::Request::Apache2->handle( $self->r );
        my %cookies;
        if ( $req->jar_status =~ /^(?:Missing input data|Success)$/ ) {
            my $jar = $req->jar;
            foreach my $key ( keys %$jar ) {
                $cookies{$key} = $jar->get($key);
            }
        }

        ## Send warning with headers to explain bad cookie
        else {
            warn(   "COOKIE ERROR: "
                  . $req->jar_status . "\n"
                  . Data::Dumper::Dumper( $self->r->headers_in() ) );
        }

------------------------------------------------------------------------

The headers which get passed back to my users look like this:

Set-Cookie: SID=n4@@GcCoAzMAAF7rnv8AAAAC|d2cb80bdcfcb60a436f99d643349f3fe14e144ec; path=/; domain=www.xxxx.com
Set-Cookie: UID=n4@@GcCoAzMAAF7rnv8AAAAC|d2cb80bdcfcb60a436f99d643349f3fe14e144ec; path=/; domain=www.xxxx.com; expires=Sun, 14-Feb-2010 13:06:36 GMT

We run various sites, all of which have Google Analytics plus usually
some other form of click tracking and advertising, which set their own
cookies.

Below are examples of Cookie headers that caused libapreq to throw one
of two errors:

Conflicting information:
------------------------

'UID=MTj9S8CoAzMAAFEq21YAAAAG|c85a9e59db92b261408eb7539ff7f949b92c7d58; $Version=0;SID=MTj9S8CoAzMAAFEq21YAAAAG|c85a9e59db92b261408eb7539ff7f949b92c7d58;$Domain=www.xxxx.com;$Path=/'

'UID=Gh9VxX8AAAIAAHP7h6AAAAAC|2e809a9cc99c2dca778c385ebdefc5cb86c95dc3; SID=Gh9VxX8AAAIAAHP7h6AAAAAC|2e809a9cc99c2dca778c385ebdefc5cb86c95dc3; $Version=1'

'UID=hCijN8CoAzMAAGVDO2QAAAAF|50299f079343fd6146257c105b1370f2da78246a; SID=hCijN8CoAzMAAGVDO2QAAAAF|50299f079343fd6146257c105b1370f2da78246a; $Path="/"; $Domain="www.xxxx.com"'
 
Expected token not present:
---------------------------
'SID=66XUEH8AAAIAAFmLLRkAAAAV|2a48c4ae2e9fb8355e75192db211f0779bdce244; UID=66XUEH8AAAIAAFmLLRkAAAAV|2a48c4ae2e9fb8355e75192db211f0779bdce244; __utma=144149162.4479471199095321000.1234471650.1234471650.1234471650.1; __utmb=144149162.24.10.1234471650; __utmc=144149162; __utmz=144149162.1234471650.1.1.utmcsr=szukaj.xxxx.pl|utmccn=(referral)|utmcmd=referral|utmcct=/internet/0,0.html'

'WT_FPC=id=78.148.13.97-777714384.29979421:lv=1234389239171:ss=1234389209078; UID=ndQ7wcCoAzMAADBMGcwAAAAD|b5258531df5af353b4a83d04ddad6b052a8866ec; __utma=236807049.987764738711978600.1231894870.1234108075.1234389209.15; __utmz=236807049.1232715122.8.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=www,xxxx.com'

'SID=6mF@x38AAAIAAFmFGtQAAAAJ|c1cabdde0a4f88c471ee7f1b1c3542138f4c61f2; UID=6mF@x38AAAIAAFmFGtQAAAAJ|c1cabdde0a4f88c471ee7f1b1c3542138f4c61f2; __utma=144149162.4479471199095321000.1234471650.1234471650.1234471650.1; __utmb=144149162.24.10.1234471650; __utmc=144149162; __utmz=144149162.1234471650.1.1.utmcsr=szukaj.xxxx.pl|utmccn=(referral)|utmcmd=referral|utmcct=/internet/0,0.html'

'SID=QSRiVn8AAAIAAA3qaCoAAAAJ|ff123ba06ae6de89a6453201465331d05276d153; UID=QSRiVn8AAAIAAA3qaCoAAAAJ|ff123ba06ae6de89a6453201465331d05276d153; __utma=144149162.2660401822504105500.1234181059.1234181059.1234181059.1; __utmb=144149162.5.10.1234181059; __utmc=144149162; __utmz=144149162.1234181059.1.1.utmcsr=szukaj.xxxx.pl|utmccn=(referral)|utmcmd=referral|utmcct=/internet/0,0.html'

I realise that the cookies themselves may not be compliant, either
because of bad JS or buggy clients, but CGI.pm manages to parse all of
the examples below, in the same way that browsers try to cope with dodgy
HTML. It'd be nice if libapreq were a bit more DWIM.

hope this info helps

thanks

Clint




Re: Cookie parsing errors: conflicting information, expected token not present

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Clinton Gormley <cl...@traveljury.com>
> To: Joe Schaefer <jo...@yahoo.com>
> Cc: Clinton Gormley <cl...@traveljury.com>; apreq-dev@httpd.apache.org
> Sent: Monday, February 16, 2009 5:09:46 AM
> Subject: Re: Cookie parsing errors: conflicting information, expected token not present
> 
> 
> > Tell you what I'll do- I'll throw the cookie headers you mentioned earlier
> > into the test suite and see if I can adjust the parser to make better sense
> > of them (no promises tho).  What won't change is the error behavior- apreq
> > will throw an error on invalid cookie headers, to alert you that the data
> > in the header is malformed and may not be parsed faithfully.  If you still
> > want to work with the data, you can always do that by using the error object
> > as if it were an ordinary APR::Request object.
> 
> That's interesting - I didn't know you could do that.

APR::Request::Error is a subclass of APR::Request.  What it does differently from
APR::Request is that it runs all the commands with errors disabled.  Most of the
stuff you are worried about would be adequately handled by just doing something
silly like

   my $req = APR::Request::Apache2->handle($r);
   my $jar = eval {$req->jar} || $@->jar; # best effort


      

Re: Cookie parsing errors: conflicting information, expected token not present

Posted by Clinton Gormley <cl...@traveljury.com>.
> Tell you what I'll do- I'll throw the cookie headers you mentioned earlier
> into the test suite and see if I can adjust the parser to make better sense
> of them (no promises tho).  What won't change is the error behavior- apreq
> will throw an error on invalid cookie headers, to alert you that the data
> in the header is malformed and may not be parsed faithfully.  If you still
> want to work with the data, you can always do that by using the error object
> as if it were an ordinary APR::Request object.

That's interesting - I didn't know you could do that.

thanks - will await your results with interest :)

clint
> 
> 
>       


Re: Cookie parsing errors: conflicting information, expected token not present

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Clinton Gormley <cl...@traveljury.com>
> To: Joe Schaefer <jo...@yahoo.com>
> Cc: Clinton Gormley <cl...@traveljury.com>; apreq-dev@httpd.apache.org
> Sent: Monday, February 16, 2009 4:34:35 AM
> Subject: Re: Cookie parsing errors: conflicting information, expected token not present
> 
> Hiya Joe
> 
> > > I realise that the cookies themselves may not be compliant, either
> > > because of bad JS or buggy clients, but CGI.pm manages to parse all of
> > > the examples below, in the same way that browsers try to cope with dodgy
> > > HTML. It'd be nice if libapreq were a bit more DWIM.
> > 
> > apreq is written to be standards compliant, and although more DWIM might be
> > nice, it shouldn't come at a cost of violating the specifications (IMO).
> 
> Well, this same argument has been put forward about whether browsers
> should just refuse to display invalid HTML, thus breaking most of the
> web, or continue trying to do the best with the information available to
> them.
> 
> I'm fully in favour of being standards compliant, and I try to ensure
> that everything that I create IS standards compliant, but we also have
> to deal with browsers with myriad bugs, and it feels a bit lame to just
> refuse to communicate with their users, no?

Tell you what I'll do- I'll throw the cookie headers you mentioned earlier
into the test suite and see if I can adjust the parser to make better sense
of them (no promises tho).  What won't change is the error behavior- apreq
will throw an error on invalid cookie headers, to alert you that the data
in the header is malformed and may not be parsed faithfully.  If you still
want to work with the data, you can always do that by using the error object
as if it were an ordinary APR::Request object.


      

Re: Cookie parsing errors: conflicting information, expected token not present

Posted by Clinton Gormley <cl...@traveljury.com>.
Hiya Joe

> > I realise that the cookies themselves may not be compliant, either
> > because of bad JS or buggy clients, but CGI.pm manages to parse all of
> > the examples below, in the same way that browsers try to cope with dodgy
> > HTML. It'd be nice if libapreq were a bit more DWIM.
> 
> apreq is written to be standards compliant, and although more DWIM might be
> nice, it shouldn't come at a cost of violating the specifications (IMO).

Well, this same argument has been put forward about whether browsers
should just refuse to display invalid HTML, thus breaking most of the
web, or continue trying to do the best with the information available to
them.

I'm fully in favour of being standards compliant, and I try to ensure
that everything that I create IS standards compliant, but we also have
to deal with browsers with myriad bugs, and it feels a bit lame to just
refuse to communicate with their users, no?

clint
     


Re: Cookie parsing errors: conflicting information, expected token not present

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Clinton Gormley <cl...@traveljury.com>
> To: apreq-dev@httpd.apache.org
> Sent: Saturday, February 14, 2009 8:21:51 AM
> Subject: Cookie parsing errors: conflicting information, expected token not present
> 
> Hiya
> 
> There has been some discussion about cookie parsing errors with
> libapreq2 on the modperl list, and Joe Schafer said:
> 
>     What version of apreq was this?  And did you report it to the     
>     apreq-dev@ mailing list?
> 
> While I have previously reported the errors I see to the modperl list, I
> thought I'd send them here as well.
> 
> This is in apache 2.2.4 with libapreq2-2.08, on linux x86_64.
> 
> The code I use to parse the cookies is as follows:
> 
> ------------------------------------------------------------------------
>         my $req = APR::Request::Apache2->handle( $self->r );
>         my %cookies;
>         if ( $req->jar_status =~ /^(?:Missing input data|Success)$/ ) {
>             my $jar = $req->jar;
>             foreach my $key ( keys %$jar ) {
>                 $cookies{$key} = $jar->get($key);
>             }
>         }
> 
>         ## Send warning with headers to explain bad cookie
>         else {
>             warn(   "COOKIE ERROR: "
>                   . $req->jar_status . "\n"
>                   . Data::Dumper::Dumper( $self->r->headers_in() ) );
>         }
> 
> ------------------------------------------------------------------------
> 
> The headers which get passed back to my users look like this:
> 
> Set-Cookie: 
> SID=n4@@GcCoAzMAAF7rnv8AAAAC|d2cb80bdcfcb60a436f99d643349f3fe14e144ec; path=/; 
> domain=www.xxxx.com
> Set-Cookie: 
> UID=n4@@GcCoAzMAAF7rnv8AAAAC|d2cb80bdcfcb60a436f99d643349f3fe14e144ec; path=/; 
> domain=www.xxxx.com; expires=Sun, 14-Feb-2010 13:06:36 GMT
> 
> We run various sites, all of which have Google Analytics plus usually
> some other form of click tracking and advertising, which set their own
> cookies.
> 
> Below are examples of Cookie headers that caused libapreq to throw one
> of two errors:
> 
> Conflicting information:
> ------------------------
> 
> 'UID=MTj9S8CoAzMAAFEq21YAAAAG|c85a9e59db92b261408eb7539ff7f949b92c7d58; 
> $Version=0;SID=MTj9S8CoAzMAAFEq21YAAAAG|c85a9e59db92b261408eb7539ff7f949b92c7d58;$Domain=www.xxxx.com;$Path=/'

Should be $Version=1, as there is no specification that describes $Version=0.

> 'UID=Gh9VxX8AAAIAAHP7h6AAAAAC|2e809a9cc99c2dca778c385ebdefc5cb86c95dc3; 
> SID=Gh9VxX8AAAIAAHP7h6AAAAAC|2e809a9cc99c2dca778c385ebdefc5cb86c95dc3; 
> $Version=1'

The $Version=1 string needs to precede the cookie, not follow it.

> 'UID=hCijN8CoAzMAAGVDO2QAAAAF|50299f079343fd6146257c105b1370f2da78246a; 
> SID=hCijN8CoAzMAAGVDO2QAAAAF|50299f079343fd6146257c105b1370f2da78246a; 
> $Path="/"; $Domain="www.xxxx.com"'

Missing a $Version=1 token.

> Expected token not present:

[...]

All of these have commas in them, which is disallowed by every cookie spec.

> I realise that the cookies themselves may not be compliant, either
> because of bad JS or buggy clients, but CGI.pm manages to parse all of
> the examples below, in the same way that browsers try to cope with dodgy
> HTML. It'd be nice if libapreq were a bit more DWIM.

apreq is written to be standards compliant, and although more DWIM might be
nice, it shouldn't come at a cost of violating the specifications (IMO).


      

Re: Cookie parsing errors: conflicting information, expected token not present

Posted by Clinton Gormley <cl...@traveljury.com>.
> If you think CGI::Cookie (which is what CGI.pm uses) parses these cookies
> correctly, you really haven't looked carefully enough.  The only thing
> CGI::Cookie does differently from libapreq2 is that it doesn't throw errors
> on stuff it doesn't understand.  Whether that's a bug or a feature is
> more a matter of taste than anything else.

Sure - what I really meant was, CGI::Cookie returns the correct value
for the cookies that I set (ie SID and UID) which are really the only
two I care about.

What I'm actually doing in these circumstances is catching the errors
and setting my cookies_enabled() flag to false, which maybe is the
better option anyway.

clint


Re: Cookie parsing errors: conflicting information, expected token not present

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Clinton Gormley <cl...@traveljury.com>
> To: apreq-dev@httpd.apache.org
> Sent: Saturday, February 14, 2009 8:21:51 AM
> Subject: Cookie parsing errors: conflicting information, expected token not present

[...]

> I realise that the cookies themselves may not be compliant, either
> because of bad JS or buggy clients, but CGI.pm manages to parse all of
> the examples below, in the same way that browsers try to cope with dodgy
> HTML. It'd be nice if libapreq were a bit more DWIM.

If you think CGI::Cookie (which is what CGI.pm uses) parses these cookies
correctly, you really haven't looked carefully enough.  The only thing
CGI::Cookie does differently from libapreq2 is that it doesn't throw errors
on stuff it doesn't understand.  Whether that's a bug or a feature is
more a matter of taste than anything else.