Skip to content

Commit

Permalink
added static files traversal tests and squashed
Browse files Browse the repository at this point in the history
  • Loading branch information
dmanto committed May 8, 2018
1 parent 201a4c1 commit 67a2f86
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/Mojolicious/Static.pm
Expand Up @@ -34,7 +34,8 @@ sub dispatch {
return undef unless my @parts = @{$path->canonicalize->parts};

# Serve static file and prevent path traversal
return undef if $parts[0] eq '..' || !$self->serve($c, join('/', @parts));
my $canon_path = join '/', @parts;
return undef if $canon_path =~ /^\.\.\/|\\/ || !$self->serve($c, $canon_path);
$stash->{'mojo.static'} = 1;
return !!$c->rendered;
}
Expand Down
19 changes: 19 additions & 0 deletions t/mojolicious/app.t
Expand Up @@ -414,11 +414,30 @@ $t->get_ok('/hello.txt')->status_is(200)
$t->get_ok('/../../mojolicious/secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')->content_like(qr/Page not found/);

# Try to access a file which is not under the web root via path
# traversal (goes back and forth one directory)
$t->get_ok('/another/../../../mojolicious/secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')->content_like(qr/Page not found/);

# Try to access a file which is not under the web root via path
# traversal (triple dot)
$t->get_ok('/.../mojolicious/secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')->content_like(qr/Page not found/);

# Try to access a file which is not under the web root via path
# traversal (backslashes)
$t->get_ok('/..\\..\\mojolicious\\secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')->content_like(qr/Page not found/);

# Try to access a file which is not under the web root via path
# traversal (escaped backslashes)
$t->get_ok('/..%5C..%5Cmojolicious%5Csecret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')->content_like(qr/Page not found/);

# Check that backslashes on query or fragment parts don't block access
$t->get_ok('/another/file?one=\\1#two=\\2')->status_is(200)
->content_like(qr/Hello Mojolicious!/);

# Check If-Modified-Since
$t->get_ok('/hello.txt' => {'If-Modified-Since' => $mtime})->status_is(304)
->header_is(Server => 'Mojolicious (Perl)')->content_is('');
Expand Down
15 changes: 15 additions & 0 deletions t/mojolicious/production_app.t
Expand Up @@ -107,6 +107,21 @@ $t->get_ok('/../../mojolicious/secret.txt')->status_is(404)
$t->get_ok('/.../mojolicious/secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')->content_like(qr/Page not found/);

# Try to access a file which is not under the web root via path
# traversal in production mode (backslashes)
$t->get_ok('/..\\..\\mojolicious\\secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')->content_like(qr/Page not found/);

# Try to access a file which is not under the web root via path
# traversal in production mode (escaped backslashes)
$t->get_ok('/..%5C..%5Cmojolicious%5Csecret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')->content_like(qr/Page not found/);

# Check that backslashes on query or fragment parts don't block access
# in production mode
$t->get_ok('/hello.txt?one=\\1#two=\\2')->status_is(200)
->content_like(qr/Hello Mojo from a static file!/);

# Embedded production static file
$t->get_ok('/some/static/file.txt')->status_is(200)
->header_is(Server => 'Mojolicious (Perl)')
Expand Down
23 changes: 23 additions & 0 deletions t/mojolicious/testing_app.t
Expand Up @@ -45,10 +45,33 @@ $t->get_ok('/../../mojolicious/secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')
->content_like(qr/Testing not found/);

# Try to access a file which is not under the web root via path
# traversal in testing mode (goes back and forth one directory)
$t->get_ok('/another/../../../mojolicious/secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')
->content_like(qr/Testing not found/);

# Try to access a file which is not under the web root via path
# traversal in testing mode (triple dot)
$t->get_ok('/.../mojolicious/secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')
->content_like(qr/Testing not found/);

# Try to access a file which is not under the web root via path
# traversal in testing mode (backslashes)
$t->get_ok('/..\\..\\mojolicious\\secret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')
->content_like(qr/Testing not found/);

# Try to access a file which is not under the web root via path
# traversal in testing mode (escaped backslashes)
$t->get_ok('/..%5C..%5Cmojolicious%5Csecret.txt')->status_is(404)
->header_is(Server => 'Mojolicious (Perl)')
->content_like(qr/Testing not found/);

# Check that backslashes on query or fragment parts don't block access
# in testing mode
$t->get_ok('/hello.txt?one=\\1#two=\\2')->status_is(200)
->content_like(qr/Hello Mojo from a static file!/);

done_testing();

0 comments on commit 67a2f86

Please sign in to comment.