diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py index 0e585f796..3cd841484 100644 --- a/winbuild/build_prepare.py +++ b/winbuild/build_prepare.py @@ -469,31 +469,23 @@ def extract_dep(url, filename): raise RuntimeError(ex) print("Extracting " + filename) + sources_dir_abs = os.path.abspath(sources_dir) if filename.endswith(".zip"): with zipfile.ZipFile(file) as zf: + for member in zf.namelist(): + member_abspath = os.path.abspath(os.path.join(sources_dir, member)) + member_prefix = os.path.commonprefix([sources_dir_abs, member_abspath]) + if sources_dir_abs != member_prefix: + raise RuntimeError("Attempted Path Traversal in Zip File") zf.extractall(sources_dir) elif filename.endswith(".tar.gz") or filename.endswith(".tgz"): with tarfile.open(file, "r:gz") as tgz: - def is_within_directory(directory, target): - - abs_directory = os.path.abspath(directory) - abs_target = os.path.abspath(target) - - prefix = os.path.commonprefix([abs_directory, abs_target]) - - return prefix == abs_directory - - def safe_extract(tar, path=".", members=None, *, numeric_owner=False): - - for member in tar.getmembers(): - member_path = os.path.join(path, member.name) - if not is_within_directory(path, member_path): - raise Exception("Attempted Path Traversal in Tar File") - - tar.extractall(path, members, numeric_owner=numeric_owner) - - - safe_extract(tgz, sources_dir) + for member in tgz.getmembers(): + member_abspath = os.path.abspath(os.path.join(sources_dir, member.name)) + member_prefix = os.path.commonprefix([sources_dir_abs, member_abspath]) + if sources_dir_abs != member_prefix: + raise RuntimeError("Attempted Path Traversal in Tar File") + tgz.extractall(sources_dir) else: raise RuntimeError("Unknown archive type: " + filename)