diff --git a/views/utils/io.py b/views/utils/io.py index a759d47..92b652a 100644 --- a/views/utils/io.py +++ b/views/utils/io.py @@ -174,7 +174,26 @@ def unpack_tarfile(path_tar: str, dir_destination: str) -> List[str]: f"unpacking tarfile at {path_tar} " f"with {len(members)} members to {dir_destination}" ) - f.extractall(path=dir_destination) + 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(f, path=dir_destination) return [os.path.join(dir_destination, member.name) for member in members]