diff --git a/test/data/jwilk-path-traversal-samples/README.md b/test/data/path_traversal/jwilk/README.md similarity index 100% rename from test/data/jwilk-path-traversal-samples/README.md rename to test/data/path_traversal/jwilk/README.md diff --git a/test/data/jwilk-path-traversal-samples/absolute1.zip b/test/data/path_traversal/jwilk/absolute1.zip similarity index 100% rename from test/data/jwilk-path-traversal-samples/absolute1.zip rename to test/data/path_traversal/jwilk/absolute1.zip diff --git a/test/data/jwilk-path-traversal-samples/absolute2.zip b/test/data/path_traversal/jwilk/absolute2.zip similarity index 100% rename from test/data/jwilk-path-traversal-samples/absolute2.zip rename to test/data/path_traversal/jwilk/absolute2.zip diff --git a/test/data/jwilk-path-traversal-samples/dirsymlink.zip b/test/data/path_traversal/jwilk/dirsymlink.zip similarity index 100% rename from test/data/jwilk-path-traversal-samples/dirsymlink.zip rename to test/data/path_traversal/jwilk/dirsymlink.zip diff --git a/test/data/jwilk-path-traversal-samples/dirsymlink2a.zip b/test/data/path_traversal/jwilk/dirsymlink2a.zip similarity index 100% rename from test/data/jwilk-path-traversal-samples/dirsymlink2a.zip rename to test/data/path_traversal/jwilk/dirsymlink2a.zip diff --git a/test/data/jwilk-path-traversal-samples/dirsymlink2b.zip b/test/data/path_traversal/jwilk/dirsymlink2b.zip similarity index 100% rename from test/data/jwilk-path-traversal-samples/dirsymlink2b.zip rename to test/data/path_traversal/jwilk/dirsymlink2b.zip diff --git a/test/data/jwilk-path-traversal-samples/relative0.zip b/test/data/path_traversal/jwilk/relative0.zip similarity index 100% rename from test/data/jwilk-path-traversal-samples/relative0.zip rename to test/data/path_traversal/jwilk/relative0.zip diff --git a/test/data/jwilk-path-traversal-samples/relative2.zip b/test/data/path_traversal/jwilk/relative2.zip similarity index 100% rename from test/data/jwilk-path-traversal-samples/relative2.zip rename to test/data/path_traversal/jwilk/relative2.zip diff --git a/test/data/jwilk-path-traversal-samples/symlink.zip b/test/data/path_traversal/jwilk/symlink.zip similarity index 100% rename from test/data/jwilk-path-traversal-samples/symlink.zip rename to test/data/path_traversal/jwilk/symlink.zip diff --git a/test/data/path_traversal/tuzovakaoff/README.md b/test/data/path_traversal/tuzovakaoff/README.md new file mode 100644 index 00000000..4bfd8cb6 --- /dev/null +++ b/test/data/path_traversal/tuzovakaoff/README.md @@ -0,0 +1,3 @@ +# Path Traversal Samples + +Copied from https://github.com/jwilk/path-traversal-samples on 2018-08-25. diff --git a/test/data/absolutepath.zip b/test/data/path_traversal/tuzovakaoff/absolutepath.zip similarity index 100% rename from test/data/absolutepath.zip rename to test/data/path_traversal/tuzovakaoff/absolutepath.zip diff --git a/test/data/symlink.zip b/test/data/path_traversal/tuzovakaoff/symlink.zip similarity index 100% rename from test/data/symlink.zip rename to test/data/path_traversal/tuzovakaoff/symlink.zip diff --git a/test/entry_test.rb b/test/entry_test.rb index eaa9c0d9..b49783d3 100644 --- a/test/entry_test.rb +++ b/test/entry_test.rb @@ -151,40 +151,4 @@ def test_store_file_without_compression assert_match(/mimetypeapplication\/epub\+zip/, first_100_bytes) end - - def test_entry_name_with_absolute_path_does_not_extract - path = '/tmp/file.txt' - File.delete(path) if File.exist?(path) - - Zip::File.open('test/data/absolutepath.zip') do |zip_file| - zip_file.each do |entry| - entry.extract - end - end - - refute File.exist?(path) - end - - def test_entry_name_with_absolute_path_extract_when_given_different_path - path = '/tmp/CVE-2018-1000544' - FileUtils.rm_rf(path) if Dir.exist?(path) - - Zip::File.open('test/data/absolutepath.zip') do |zip_file| - zip_file.each do |entry| - entry.extract("#{path}/#{entry.name}") - end - end - - assert File.exist?("#{path}/tmp/file.txt") - end - - def test_entry_name_with_relative_symlink - assert_raises Errno::ENOENT do - Zip::File.open('test/data/symlink.zip') do |zip_file| - zip_file.each do |entry| - entry.extract - end - end - end - end end diff --git a/test/path_traversal_test.rb b/test/path_traversal_test.rb index ab8269b7..406fc0ef 100644 --- a/test/path_traversal_test.rb +++ b/test/path_traversal_test.rb @@ -1,8 +1,11 @@ class PathTraversalTest < MiniTest::Test - TEST_FILE_ROOT = File.absolute_path('test/data/jwilk-path-traversal-samples') + TEST_FILE_ROOT = File.absolute_path('test/data/path_traversal') def setup - FileUtils.rm_f '/tmp/moo' # with apologies to anyone using this file + # With apologies to anyone using these files... but they are the files in + # the sample zips, so we don't have much choice here. + FileUtils.rm_f '/tmp/moo' + FileUtils.rm_f '/tmp/file.txt' end def extract_path_traversal_zip(name) @@ -17,72 +20,102 @@ def in_tmpdir Dir.mktmpdir do |tmp| test_path = File.join(tmp, 'test') Dir.mkdir test_path - Dir.chdir(test_path) do - yield + Dir.chdir test_path do + yield test_path end end end def test_leading_slash in_tmpdir do - extract_path_traversal_zip 'absolute1.zip' - assert !File.exist?('/tmp/moo') + extract_path_traversal_zip 'jwilk/absolute1.zip' + refute File.exist?('/tmp/moo') end end def test_multiple_leading_slashes in_tmpdir do - extract_path_traversal_zip 'absolute2.zip' - assert !File.exist?('/tmp/moo') + extract_path_traversal_zip 'jwilk/absolute2.zip' + refute File.exist?('/tmp/moo') end end def test_leading_dot_dot in_tmpdir do - extract_path_traversal_zip 'relative0.zip' - assert !File.exist?('../moo') + extract_path_traversal_zip 'jwilk/relative0.zip' + refute File.exist?('../moo') end end def test_non_leading_dot_dot in_tmpdir do - extract_path_traversal_zip 'relative2.zip' - assert !File.exist?('../moo') + extract_path_traversal_zip 'jwilk/relative2.zip' + refute File.exist?('../moo') end end def test_file_symlink in_tmpdir do - extract_path_traversal_zip 'symlink.zip' + extract_path_traversal_zip 'jwilk/symlink.zip' assert File.exist?('moo') - assert !File.exist?('/tmp/moo') + refute File.exist?('/tmp/moo') end end def test_directory_symlink in_tmpdir do - extract_path_traversal_zip 'dirsymlink.zip' - assert !File.exist?('/tmp/moo') + extract_path_traversal_zip 'jwilk/dirsymlink.zip' + refute File.exist?('/tmp/moo') end end def test_two_directory_symlinks_a in_tmpdir do - # Can't create par/moo because the symlink par is skipped. + # Can't create par/moo because the symlinks are skipped. assert_raises Errno::ENOENT do - extract_path_traversal_zip 'dirsymlink2a.zip' + extract_path_traversal_zip 'jwilk/dirsymlink2a.zip' end - assert File.exist?('cur') - assert_equal '.', File.readlink('cur') + refute File.exist?('cur') + refute File.exist?('par') + refute File.exist?('par/moo') end end def test_two_directory_symlinks_b in_tmpdir do - extract_path_traversal_zip 'dirsymlink2b.zip' + extract_path_traversal_zip 'jwilk/dirsymlink2b.zip' assert File.exist?('cur') assert_equal '.', File.readlink('cur') - assert !File.exist?('../moo') + refute File.exist?('../moo') + end + end + + def test_entry_name_with_absolute_path_does_not_extract + in_tmpdir do + extract_path_traversal_zip 'tuzovakaoff/absolutepath.zip' + refute File.exist?('/tmp/file.txt') + end + end + + def test_entry_name_with_absolute_path_extract_when_given_different_path + in_tmpdir do |test_path| + zip_path = File.join(TEST_FILE_ROOT, 'tuzovakaoff/absolutepath.zip') + Zip::File.open(zip_path) do |zip_file| + zip_file.each do |entry| + entry.extract(File.join(test_path, entry.name)) + end + end + refute File.exist?('/tmp/file.txt') + end + end + + def test_entry_name_with_relative_symlink + in_tmpdir do + # Doesn't create the symlink path, so can't create path/file.txt. + assert_raises Errno::ENOENT do + extract_path_traversal_zip 'tuzovakaoff/symlink.zip' + end + refute File.exist?('/tmp/file.txt') end end end