diff --git a/buildscripts/mobile/benchrun_embedded_setup_android.py b/buildscripts/mobile/benchrun_embedded_setup_android.py index 92f18d33..ae667e89 100644 --- a/buildscripts/mobile/benchrun_embedded_setup_android.py +++ b/buildscripts/mobile/benchrun_embedded_setup_android.py @@ -32,7 +32,26 @@ def download_and_untar(url, root_dir): LOGGER.info("Downloading %s", url) urllib.urlretrieve(url, temp_file) with tarfile.open(temp_file, "r:gz") as tar: - tar.extractall(root_dir) + 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, root_dir) os.remove(temp_file) diff --git a/buildscripts/resmoke.py b/buildscripts/resmoke.py index 2094610d..ecba90e8 100644 --- a/buildscripts/resmoke.py +++ b/buildscripts/resmoke.py @@ -345,7 +345,26 @@ def _setup_jasper(self): "curator-dist-%s-%s.tar.gz") % (os_platform, git_hash) response = requests.get(url, stream=True) with tarfile.open(mode="r|gz", fileobj=response.raw) as tf: - tf.extractall(path="./build/") + 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(tf, path="./build/") jasper_port = config.BASE_PORT - 1 jasper_conn_str = "localhost:%d" % jasper_port diff --git a/pytests/powertest.py b/pytests/powertest.py index 5ae6f7b7..9b923e94 100644 --- a/pytests/powertest.py +++ b/pytests/powertest.py @@ -484,7 +484,26 @@ def install_tarball(tarball, root_dir): ext = get_extension(tarball) if ext == ".tgz": with tarfile.open(tarball, "r:gz") as tar_handle: - tar_handle.extractall(path=root_dir) + 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_handle, path=root_dir) output = "Unzipped {} to {}: {}".format(tarball, root_dir, tar_handle.getnames()) ret = 0 elif ext == ".zip":