Skip to content
Permalink
Browse files

Merge pull request #1217 from dmanto/block-windows-path-traverses

added static files traversal tests and squashed
  • Loading branch information...
kraih committed May 11, 2018
2 parents fd5a9f9 + 67a2f86 commit 23ebe051d9378f0f122e3c908845fc0c2cae0106
Showing with 59 additions and 1 deletion.
  1. +2 −1 lib/Mojolicious/Static.pm
  2. +19 −0 t/mojolicious/app.t
  3. +15 −0 t/mojolicious/production_app.t
  4. +23 −0 t/mojolicious/testing_app.t
@@ -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;
}
@@ -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('');
@@ -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)')
@@ -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 23ebe05

Please sign in to comment.
You can’t perform that action at this time.