diff --git a/convert_jeff33.py b/convert_jeff33.py index 18578960..77da8894 100755 --- a/convert_jeff33.py +++ b/convert_jeff33.py @@ -109,7 +109,26 @@ class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, for f in details['compressed_files']: with tarfile.open(download_path / f, 'r') as tgz: print(f'Extracting {f}...') - tgz.extractall(path=ace_files_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(tgz, path=ace_files_dir) if args.cleanup and download_path.exists(): rmtree(download_path) diff --git a/convert_nndc71.py b/convert_nndc71.py index addee17b..4a626cf6 100755 --- a/convert_nndc71.py +++ b/convert_nndc71.py @@ -143,7 +143,29 @@ class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, else: with tarfile.open(download_path / particle / f, 'r') as tgz: print(f'Extracting {f}...') - tgz.extractall(path=extraction_dir) + + import os + + 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, path=extraction_dir) if args.cleanup and download_path.exists(): rmtree(download_path) diff --git a/convert_tendl.py b/convert_tendl.py index 824ae1ae..92c36194 100755 --- a/convert_tendl.py +++ b/convert_tendl.py @@ -126,7 +126,29 @@ class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, for f in release_details[args.release]['compressed_files']: with tarfile.open(download_path / f, 'r') as tgz: print(f'Extracting {f}...') - tgz.extractall(path=ace_files_dir) + + import os + + 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, path=ace_files_dir) if args.cleanup and download_path.exists(): rmtree(download_path) diff --git a/generate_jeff33.py b/generate_jeff33.py index af93051b..bcd53800 100755 --- a/generate_jeff33.py +++ b/generate_jeff33.py @@ -139,7 +139,26 @@ def sort_key(path): elif f.endswith('.tar.gz') or f.endswith('.tgz'): print(f'Extracting {f}...') with tarfile.open(f) as tgz: - tgz.extractall() + 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) # ========================================================================= # REPLACE C13 AND O17 WITH FILES FROM TENDL 2019 diff --git a/make_compton.py b/make_compton.py index 8ff892f1..1bbb5383 100755 --- a/make_compton.py +++ b/make_compton.py @@ -25,7 +25,29 @@ if not g4dir.is_dir(): with tarfile.open(filename, 'r') as tgz: print(f'Extracting {filename}...') - tgz.extractall() + + import os + + 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) # ============================================================================== # GENERATE COMPTON PROFILE HDF5 FILE