Fix CVE-2018-1000544 absolute path traversal
Small refactor along the way to centralize destination handling when no explicit path is given and a potential malicious one from the zipfile is used
This commit is contained in:
parent
e89f6aca44
commit
6e0d23178a
|
@ -147,14 +147,18 @@ module Zip
|
||||||
end
|
end
|
||||||
|
|
||||||
# Extracts entry to file dest_path (defaults to @name).
|
# Extracts entry to file dest_path (defaults to @name).
|
||||||
def extract(dest_path = @name, &block)
|
def extract(dest_path = nil, &block)
|
||||||
block ||= proc { ::Zip.on_exists_proc }
|
if dest_path.nil? && Pathname.new(@name).absolute?
|
||||||
|
puts "WARNING: skipped absolute path in #{@name}"
|
||||||
if @name.squeeze('/') =~ /\.{2}(?:\/|\z)/
|
return self
|
||||||
|
elsif @name.squeeze('/') =~ /\.{2}(?:\/|\z)/
|
||||||
puts "WARNING: skipped \"../\" path component(s) in #{@name}"
|
puts "WARNING: skipped \"../\" path component(s) in #{@name}"
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
dest_path ||= @name
|
||||||
|
block ||= proc { ::Zip.on_exists_proc }
|
||||||
|
|
||||||
if directory? || file? || symlink?
|
if directory? || file? || symlink?
|
||||||
__send__("create_#{@ftype}", dest_path, &block)
|
__send__("create_#{@ftype}", dest_path, &block)
|
||||||
else
|
else
|
||||||
|
|
Binary file not shown.
|
@ -151,4 +151,30 @@ class ZipEntryTest < MiniTest::Test
|
||||||
|
|
||||||
assert_match(/mimetypeapplication\/epub\+zip/, first_100_bytes)
|
assert_match(/mimetypeapplication\/epub\+zip/, first_100_bytes)
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue