Browse files

Fix a bug in read_cookie's code path when using the single-arg form

This issue was caused by a bug in the interchange read_cookie codepath
which was being too lentient about its parsing of $CGI::cookie when
looking up a specific cookie's value.

Certain $CGI::cookie strings and requested cookie names can result in
returning the wrong value for the cookie given the following
circumstances: $CGI::cookie contains a value portion of the keyvalue
pairs which include a word-break character, the (case-insensitive)
target name and then an equals sign.  Additionally, this matching
substring would need to appear before the actual cookie for the key in


  'foo.tracker={"url":"","count":3}; MV_SOURCE=foo'

[read-cookie] without arguments would correctly parse and return the
expected keypairs, however [read-cookie MV_SOURCE] would scan the
$CGI::cookie string for a word-break, the specific cookie name, a
literal '=' and then proceed to return the literal:

  MV_SOURCE => 'blah","count":3}'

This fix tightens up the parsing to only look at the start of the
string or immediately after a ';' (with optional whitespace between)
when parsing a specific cookie value.

Some additional comments:

I had difficulty locating a specification for the cookie keys/values
themselves, but I wonder if we should remove the /i regex modifier, as
I'd personally expect cookie names to be case-sensitive.  Left in for

Additionally, the setter of the aforementioned cookie should likely
have used some form of uriencoding instead of having the raw '{}='
characters, however that's no excuse for us to barf on bad behavior.
  • Loading branch information...
1 parent 5a1bb86 commit e7c35832403c81764afd2509054f0c4b44b84a17 @machack666 machack666 committed Mar 9, 2011
Showing with 1 addition and 1 deletion.
  1. +1 −1 lib/Vend/
@@ -1901,7 +1901,7 @@ sub read_cookie {
my ($lookfor, $string) = @_;
$string = $CGI::cookie
unless defined $string;
- return undef unless $string =~ /\b$lookfor=([^\s;]+)/i;
+ return undef unless $string =~ /(?:^|;)\s*\Q$lookfor\E=([^\s;]+)/i;
return unescape_chars($1);

0 comments on commit e7c3583

Please sign in to comment.