Skip to content

Commit

Permalink
fix a security issue in Mojo::UserAgent::CookieJar
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Feb 13, 2018
1 parent 74e4900 commit c16a56a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
5 changes: 4 additions & 1 deletion Changes
@@ -1,5 +1,8 @@

7.66 2018-02-12
7.66 2018-02-13
- This release contains fixes for security issues, everybody should upgrade!
- Removed origin attribute of Mojo::Cookie::Response.
- Added host_only attribute to Mojo::Cookie::Response.

7.65 2018-02-11
- Added EXPERIMENTAL timing->begin, timing->elapsed, timing->rps and
Expand Down
17 changes: 9 additions & 8 deletions lib/Mojo/Cookie/Response.pm
Expand Up @@ -4,7 +4,7 @@ use Mojo::Base 'Mojo::Cookie';
use Mojo::Date;
use Mojo::Util qw(quote split_cookie_header);

has [qw(domain expires httponly max_age origin path secure)];
has [qw(domain expires host_only httponly max_age path secure)];

my %ATTRS = map { $_ => 1 } qw(domain expires httponly max-age path secure);

Expand Down Expand Up @@ -100,6 +100,14 @@ Cookie domain.
Expiration for cookie.
=head2 host_only
my $bool = $cookie->host_only;
$cookie = $cookie->host_only($bool);
Host-only flag, indicating that the canonicalized request-host is identical to
the cookie's L</"domain">.
=head2 httponly
my $bool = $cookie->httponly;
Expand All @@ -115,13 +123,6 @@ cookie.
Max age for cookie.
=head2 origin
my $origin = $cookie->origin;
$cookie = $cookie->origin('mojolicious.org');
Origin of the cookie.
=head2 path
my $path = $cookie->path;
Expand Down
20 changes: 11 additions & 9 deletions lib/Mojo/UserAgent/CookieJar.pm
Expand Up @@ -22,12 +22,11 @@ sub add {
next if length($cookie->value // '') > $size;

# Replace cookie
my $origin = $cookie->origin // '';
next unless my $domain = lc($cookie->domain // $origin);
next unless my $domain = lc($cookie->domain // '');
next unless my $path = $cookie->path;
next unless length(my $name = $cookie->name // '');
my $jar = $self->{jar}{$domain} ||= [];
@$jar = (grep({ _compare($_, $path, $name, $origin) } @$jar), $cookie);
@$jar = (grep({ _compare($_, $path, $name, $domain) } @$jar), $cookie);
}

return $self;
Expand All @@ -45,8 +44,9 @@ sub collect {
for my $cookie (@{$tx->res->cookies}) {

# Validate domain
my $host = lc $url->ihost;
my $domain = lc($cookie->domain // $cookie->origin($host)->origin);
my $host = lc $url->ihost;
$cookie->domain($host)->host_only(1) unless $cookie->domain;
my $domain = lc $cookie->domain;
if (my $cb = $self->ignore) { next if $cb->($cookie) }
next if $host ne $domain && ($host !~ /\Q.$domain\E$/ || $host =~ /\.\d+$/);

Expand All @@ -72,7 +72,7 @@ sub find {
# Grab cookies
my $new = $self->{jar}{$domain} = [];
for my $cookie (@$old) {
next unless $cookie->domain || $host eq $cookie->origin;
next if $cookie->host_only && $host ne $cookie->domain;

# Check if cookie has expired
if (defined(my $expires = $cookie->expires)) { next if time > $expires }
Expand Down Expand Up @@ -101,9 +101,11 @@ sub prepare {
}

sub _compare {
my ($cookie, $path, $name, $origin) = @_;
return 1 if $cookie->path ne $path || $cookie->name ne $name;
return ($cookie->origin // '') ne $origin;
my ($cookie, $path, $name, $domain) = @_;
return
$cookie->path ne $path
|| $cookie->name ne $name
|| $cookie->domain ne $domain;
}

sub _path { $_[0] eq '/' || $_[0] eq $_[1] || index($_[1], "$_[0]/") == 0 }
Expand Down

0 comments on commit c16a56a

Please sign in to comment.