When extracting zip files do not allow maliciously created zip files to overwrite other files on the system

This commit is contained in:
Kovid Goyal 2013-04-07 11:11:32 +05:30
parent 6d1fba3a0d
commit 9c3591a467
2 changed files with 14 additions and 5 deletions

View File

@ -174,7 +174,13 @@ def _extractall(f, path=None, file_info=None):
has_data_descriptors = header.flags & (1 << 3) has_data_descriptors = header.flags & (1 << 3)
seekval = header.compressed_size + (16 if has_data_descriptors else 0) seekval = header.compressed_size + (16 if has_data_descriptors else 0)
found = True found = True
parts = header.filename.split('/') # Sanitize path changing absolute to relative paths and removing .. and
# .
fname = header.filename.replace(os.sep, '/')
fname = os.path.splitdrive(fname)[1]
parts = [x for x in fname.split('/') if x not in {'', os.path.pardir, os.path.curdir}]
if not parts:
continue
if header.uncompressed_size == 0: if header.uncompressed_size == 0:
# Directory # Directory
f.seek(f.tell()+seekval) f.seek(f.tell()+seekval)

View File

@ -1099,10 +1099,13 @@ class ZipFile:
base_target = targetpath # Added by Kovid base_target = targetpath # Added by Kovid
# don't include leading "/" from file name if present # Sanitize path, changing absolute paths to relative paths
fname = member.filename # and removing .. and . (changed by Kovid)
if fname.startswith('/'): fname = member.filename.replace(os.sep, '/')
fname = fname[1:] fname = os.path.splitdrive(fname)[1]
fname = '/'.join(x for x in fname.split('/') if x not in {'', os.path.curdir, os.path.pardir})
if not fname:
raise BadZipfile('The member %r has an invalid name'%member.filename)
targetpath = os.path.normpath(os.path.join(base_target, fname)) targetpath = os.path.normpath(os.path.join(base_target, fname))