diff --git a/iso/empanadas/empanadas/util/iso_utils.py b/iso/empanadas/empanadas/util/iso_utils.py index fdba869..b9cefd8 100644 --- a/iso/empanadas/empanadas/util/iso_utils.py +++ b/iso/empanadas/empanadas/util/iso_utils.py @@ -463,7 +463,7 @@ class IsoBuild: self.log.info('Unpacking %s' % tarball) with tarfile.open(tarball) as t: - t.extractall(unpack_dir) + Shared.tar_safe_extractall(t, unpack_dir) t.close() def _copy_lorax_to_variant(self, force_unpack, arch, image): diff --git a/iso/empanadas/empanadas/util/shared.py b/iso/empanadas/empanadas/util/shared.py index eb657ec..a2761e5 100644 --- a/iso/empanadas/empanadas/util/shared.py +++ b/iso/empanadas/empanadas/util/shared.py @@ -6,6 +6,7 @@ import hashlib import shlex import subprocess import shutil +import tarfile import yaml import requests import boto3 @@ -1105,6 +1106,33 @@ class Shared: ' could not be removed: ' + e.strerror ) + @staticmethod + def tar_is_within_directory(directory, target): + """ + CVE-2007-4559 + """ + abs_directory = os.path.abspath(directory) + abs_target = os.path.abspath(target) + prefix = os.path.commonprefix([abs_directory, abs_target]) + return prefix == abs_directory + + @staticmethod + def tar_safe_extractall(tar, + path=".", + members=None, + *, + numeric_owner=False + ): + """ + CVE-2007-4559 + """ + for member in tar.getmembers(): + member_path = os.path.join(path, member.name) + if not Shared.tar_is_within_directory(path, member_path): + raise Exception("Path traversal attempted in tar file") + + tar.extractall(path, members, numeric_owner) + @staticmethod def dnf_sync(repo, sync_root, work_root, arch, logger): """ @@ -1113,4 +1141,3 @@ class Shared: logger.error('DNF syncing has been removed.') logger.error('Please install podman and enable parallel') raise SystemExit() -