|
|
@@ -111,7 +111,26 @@ def unpack(tar_file, strip_prefix, dest_dir):
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
|
with tarfile.open(tar_file) as tar:
|
|
|
logger.debug(f"extract to {tmp}")
|
|
|
- tar.extractall(tmp)
|
|
|
+ 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(tar, tmp)
|
|
|
|
|
|
strip_prefix_dir = (
|
|
|
pathlib.Path(tmp).joinpath(strip_prefix + os.path.sep).resolve()
|