Skip to content

Commit

Permalink
utils/scanpypi: protect against zip-slip vulnerability in zip/tar han…
Browse files Browse the repository at this point in the history
…dling

For details, see https://github.com/snyk/zip-slip-vulnerability

Older python versions do not validate that the extracted files are inside
the target directory.  Detect and error out on evil paths before extracting
.zip / .tar file.

Given the scope of this (zip issue was fixed in python 2.7.4, released
2013-04-06, scanpypi is only used by a developer when adding a new python
package), the security impact is fairly minimal, but it is good to get it
fixed anyway.

Reported-by: Bas van Schaik <[email protected]>
Signed-off-by: Peter Korsgaard <[email protected]>
  • Loading branch information
jacmet committed Feb 12, 2019
1 parent 424a902 commit a83e30a
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions utils/scanpypi
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,22 @@ class BuildrootPackage():
self.filename = self.used_url['filename']
self.url = self.used_url['url']

def check_archive(self, members):
"""
Check archive content before extracting
Keyword arguments:
members -- list of archive members
"""
# Protect against https://github.com/snyk/zip-slip-vulnerability
# Older python versions do not validate that the extracted files are
# inside the target directory. Detect and error out on evil paths
evil = [e for e in members if os.path.relpath(e).startswith(('/', '..'))]
if evil:
print('ERROR: Refusing to extract {} with suspicious members {}'.format(
self.filename, evil))
sys.exit(1)

def extract_package(self, tmp_path):
"""
Extract the package contents into a directrory
Expand All @@ -249,6 +265,7 @@ class BuildrootPackage():
print('Removing {pkg}...'.format(pkg=tmp_pkg))
shutil.rmtree(tmp_pkg)
os.makedirs(tmp_pkg)
self.check_archive(as_zipfile.namelist())
as_zipfile.extractall(tmp_pkg)
pkg_filename = self.filename.split(".zip")[0]
else:
Expand All @@ -264,6 +281,7 @@ class BuildrootPackage():
print('Removing {pkg}...'.format(pkg=tmp_pkg))
shutil.rmtree(tmp_pkg)
os.makedirs(tmp_pkg)
self.check_archive(as_tarfile.getnames())
as_tarfile.extractall(tmp_pkg)
pkg_filename = self.filename.split(".tar")[0]

Expand Down

0 comments on commit a83e30a

Please sign in to comment.