Skip to content

Commit

Permalink
fixed canonicalize in Mojo::Path to not remove parts with more than t…
Browse files Browse the repository at this point in the history
…hree dots
  • Loading branch information
kraih committed Feb 2, 2015
1 parent d6af83d commit 28652ad
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 16 deletions.
2 changes: 2 additions & 0 deletions Changes
@@ -1,5 +1,7 @@

5.77 2015-02-03
- Fixed canonicalize in Mojo::Path to not remove parts with more than three
dots.

5.76 2015-02-02
- Emergency release for a critical security issue that can expose files on
Expand Down
12 changes: 5 additions & 7 deletions lib/Mojo/Path.pm
Expand Up @@ -15,7 +15,9 @@ sub canonicalize {

my $parts = $self->parts;
for (my $i = 0; $i <= $#$parts;) {
if ($parts->[$i] =~ /^(?:\.||\.{3,})$/) { splice @$parts, $i, 1 }
if ($parts->[$i] eq '' || $parts->[$i] eq '.' || $parts->[$i] eq '...') {
splice @$parts, $i, 1;
}
elsif ($i < 1 || $parts->[$i] ne '..' || $parts->[$i - 1] eq '..') { $i++ }
else { splice @$parts, --$i, 2 }
}
Expand Down Expand Up @@ -169,9 +171,8 @@ following new ones.
$path = $path->canonicalize;
Canonicalize path by resolving C<.> and C<..>, parts comprised solely of three
or more dots are treated as a single dot to protect from path traversal
attacks.
Canonicalize path by resolving C<.> and C<..>, in addition C<...> will be
treated as C<.> to protect from path traversal attacks.
# "/foo/baz"
Mojo::Path->new('/foo/./bar/../baz')->canonicalize;
Expand All @@ -182,9 +183,6 @@ attacks.
# "/foo/bar"
Mojo::Path->new('/foo/.../bar')->canonicalize;
# "/foo/bar"
Mojo::Path->new('/foo/...../bar')->canonicalize;
=head2 clone
my $clone = $path->clone;
Expand Down
9 changes: 0 additions & 9 deletions t/mojo/path.t
Expand Up @@ -97,15 +97,6 @@ is_deeply $path->parts, [qw(foo windows win.ini)], 'right structure';
ok $path->leading_slash, 'has leading slash';
ok !$path->trailing_slash, 'no trailing slash';

# Canonicalize (more dots)
$path = Mojo::Path->new('/foo/....../windows/win.ini');
is "$path", '/foo/....../windows/win.ini', 'same path';
is_deeply $path->parts, [qw(foo ...... windows win.ini)], 'right structure';
is $path->canonicalize, '/foo/windows/win.ini', 'canonicalized path';
is_deeply $path->parts, [qw(foo windows win.ini)], 'right structure';
ok $path->leading_slash, 'has leading slash';
ok !$path->trailing_slash, 'no trailing slash';

# Canonicalizing (with escaped "%")
$path = Mojo::Path->new('%2ftest%2f..%252f..%2f..%2f..%2f..%2fetc%2fpasswd');
is "$path", '%2ftest%2f..%252f..%2f..%2f..%2f..%2fetc%2fpasswd', 'same path';
Expand Down

0 comments on commit 28652ad

Please sign in to comment.