From 8af97c431ef0c0c9fbabe92562d0a3665d82eb38 Mon Sep 17 00:00:00 2001 From: TrellixVulnTeam Date: Fri, 16 Dec 2022 03:08:18 +0000 Subject: [PATCH] Adding tarfile member sanitization to extractall() --- project/tests/fixtures/fixtures_ng.py | 21 ++++++++++++++++++- .../tap_cli/test_cli_application.py | 21 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/project/tests/fixtures/fixtures_ng.py b/project/tests/fixtures/fixtures_ng.py index 71a91c2..8641d07 100644 --- a/project/tests/fixtures/fixtures_ng.py +++ b/project/tests/fixtures/fixtures_ng.py @@ -111,6 +111,25 @@ def cli_login(tap_cli): def app_jar(test_sample_apps): sample_app_source_dir = os.path.join(TMP_FILE_DIR, "sample_java_app_source") with tarfile.open(test_sample_apps.tapng_java_app.filepath) as tar: - tar.extractall(path=sample_app_source_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, path=sample_app_source_dir) sample_app_tar_content = [name.replace("./", "", 1) for name in tar.getnames()] return os.path.join(sample_app_source_dir, next(name for name in sample_app_tar_content if name.endswith(".jar"))) diff --git a/project/tests/test_components/tap_cli/test_cli_application.py b/project/tests/test_components/tap_cli/test_cli_application.py index c655515..381f529 100644 --- a/project/tests/test_components/tap_cli/test_cli_application.py +++ b/project/tests/test_components/tap_cli/test_cli_application.py @@ -233,7 +233,26 @@ def sample_app_source_dir(self, test_sample_apps): sample_app_source_dir = os.path.join(TMP_FILE_DIR, test_sample_apps[self.SAMPLE_APP_NAME].filename) step("Extract application archive") with tarfile.open(test_sample_apps[self.SAMPLE_APP_NAME].filepath) as tar: - tar.extractall(path=sample_app_source_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, path=sample_app_source_dir) sample_app_tar_content = [name.replace("./", "", 1) for name in tar.getnames()] step("Check content of the archive") missing_files = [app_file for app_file in self.EXPECTED_FILE_LIST if app_file not in sample_app_tar_content]