rubyzip/test/path_traversal_test.rb

142 lines
3.6 KiB
Ruby
Raw Normal View History

2018-08-26 17:00:35 +08:00
class PathTraversalTest < MiniTest::Test
2018-08-26 19:13:12 +08:00
TEST_FILE_ROOT = File.absolute_path('test/data/path_traversal')
2018-08-26 17:00:35 +08:00
def setup
2018-08-26 19:13:12 +08:00
# 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'
2018-08-26 17:00:35 +08:00
end
def extract_path_traversal_zip(name)
Zip::File.open(File.join(TEST_FILE_ROOT, name)) do |zip_file|
zip_file.each do |entry|
entry.extract
end
end
end
def in_tmpdir
Dir.mktmpdir do |tmp|
test_path = File.join(tmp, 'test')
Dir.mkdir test_path
2018-08-26 19:13:12 +08:00
Dir.chdir test_path do
yield test_path
2018-08-26 17:00:35 +08:00
end
end
end
def test_leading_slash
in_tmpdir do
2018-08-26 19:13:12 +08:00
extract_path_traversal_zip 'jwilk/absolute1.zip'
refute File.exist?('/tmp/moo')
2018-08-26 17:00:35 +08:00
end
end
def test_multiple_leading_slashes
in_tmpdir do
2018-08-26 19:13:12 +08:00
extract_path_traversal_zip 'jwilk/absolute2.zip'
refute File.exist?('/tmp/moo')
2018-08-26 17:00:35 +08:00
end
end
def test_leading_dot_dot
in_tmpdir do
2018-08-26 19:13:12 +08:00
extract_path_traversal_zip 'jwilk/relative0.zip'
refute File.exist?('../moo')
2018-08-26 17:00:35 +08:00
end
end
def test_non_leading_dot_dot_with_existing_folder
in_tmpdir do
extract_path_traversal_zip 'relative1.zip'
assert Dir.exist?('tmp')
refute File.exist?('../moo')
end
end
def test_non_leading_dot_dot_without_existing_folder
2018-08-26 17:00:35 +08:00
in_tmpdir do
2018-08-26 19:13:12 +08:00
extract_path_traversal_zip 'jwilk/relative2.zip'
refute File.exist?('../moo')
2018-08-26 17:00:35 +08:00
end
end
def test_file_symlink
in_tmpdir do
2018-08-26 19:13:12 +08:00
extract_path_traversal_zip 'jwilk/symlink.zip'
2018-08-26 17:00:35 +08:00
assert File.exist?('moo')
2018-08-26 19:13:12 +08:00
refute File.exist?('/tmp/moo')
2018-08-26 17:00:35 +08:00
end
end
def test_directory_symlink
in_tmpdir do
# Can't create tmp/moo, because the tmp symlink is skipped.
assert_raises Errno::ENOENT do
extract_path_traversal_zip 'jwilk/dirsymlink.zip'
end
2018-08-26 19:13:12 +08:00
refute File.exist?('/tmp/moo')
2018-08-26 17:00:35 +08:00
end
end
def test_two_directory_symlinks_a
in_tmpdir do
2018-08-26 19:13:12 +08:00
# Can't create par/moo because the symlinks are skipped.
2018-08-26 17:00:35 +08:00
assert_raises Errno::ENOENT do
2018-08-26 19:13:12 +08:00
extract_path_traversal_zip 'jwilk/dirsymlink2a.zip'
2018-08-26 17:00:35 +08:00
end
2018-08-26 19:13:12 +08:00
refute File.exist?('cur')
refute File.exist?('par')
refute File.exist?('par/moo')
2018-08-26 17:00:35 +08:00
end
end
def test_two_directory_symlinks_b
in_tmpdir do
# Can't create par/moo, because the symlinks are skipped.
assert_raises Errno::ENOENT do
extract_path_traversal_zip 'jwilk/dirsymlink2b.zip'
end
refute File.exist?('cur')
2018-08-26 19:13:12 +08:00
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')
2018-08-26 17:00:35 +08:00
end
end
def test_entry_name_with_tilde
in_tmpdir do
extract_path_traversal_zip 'tilde.zip'
assert File.exist?('~tilde~')
end
end
2018-08-26 17:00:35 +08:00
end