From 06f32691d671bc25744d12bd578dcfde347473e6 Mon Sep 17 00:00:00 2001 From: Douglas Bagnall Date: Fri, 17 Jul 2026 12:16:49 +1200 Subject: [PATCH] safe_tarfile: check paths using the destination directory This only affects very old versions of Python. Python 3.8.18+ will use the upstream tarfile.tarfilter. BUG: https://bugzilla.samba.org/show_bug.cgi?id=16103 Signed-off-by: Douglas Bagnall --- python/samba/safe_tarfile.py | 41 +++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/python/samba/safe_tarfile.py b/python/samba/safe_tarfile.py index 88b32965c8a..84acfd2f9b1 100644 --- a/python/samba/safe_tarfile.py +++ b/python/samba/safe_tarfile.py @@ -50,29 +50,36 @@ class TarFile(UnsafeTarFile): except AttributeError: def extract(self, member, path="", set_attrs=True, *, numeric_owner=False): - self._safetarfile_check() + self._safetarfile_check(path) super().extract(member, path, set_attrs=set_attrs, numeric_owner=numeric_owner) - def extractall(self, path, members=None, *, numeric_owner=False): - self._safetarfile_check() + def extractall(self, path=".", members=None, *, numeric_owner=False): + self._safetarfile_check(path) super().extractall(path, members, numeric_owner=numeric_owner) - def _safetarfile_check(self): - for tarinfo in self.__iter__(): - if self._is_traversal_attempt(tarinfo=tarinfo): - raise ExtractError( - "Attempted directory traversal for " - f"member: {tarinfo.name}") - if self._is_unsafe_symlink(tarinfo=tarinfo): - raise ExtractError( - "Attempted directory traversal via symlink for " - f"member: {tarinfo.linkname}") - if self._is_unsafe_link(tarinfo=tarinfo): - raise ExtractError( - "Attempted directory traversal via link for " - f"member: {tarinfo.linkname}") + def _safetarfile_check(self, path): + oldcwd = os.getcwd() + if not path: + path = '.' + try: + os.chdir(path) + for tarinfo in self.__iter__(): + if self._is_traversal_attempt(tarinfo=tarinfo): + raise ExtractError( + "Attempted directory traversal for " + f"member: {tarinfo.name}") + if self._is_unsafe_symlink(tarinfo=tarinfo): + raise ExtractError( + "Attempted directory traversal via symlink for " + f"member: {tarinfo.linkname}") + if self._is_unsafe_link(tarinfo=tarinfo): + raise ExtractError( + "Attempted directory traversal via link for " + f"member: {tarinfo.linkname}") + finally: + os.chdir(oldcwd) def _resolve_path(self, path): return os.path.realpath(os.path.abspath(path)) -- 2.43.0