From b7d61d6544710f881222572d7759bedc95a7ae34 Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Mon, 4 Mar 2024 12:00:56 -0600 Subject: [PATCH] Use tar.extractall(filter="data") on Python>=3.12 --- shinylive/_utils.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/shinylive/_utils.py b/shinylive/_utils.py index e2136e4..961fd9b 100644 --- a/shinylive/_utils.py +++ b/shinylive/_utils.py @@ -107,17 +107,24 @@ def copy_fn(src: str, dst: str, follow_symlinks: bool = True) -> None: # Wrapper for TarFile.extractall(), to avoid CVE-2007-4559. def tar_safe_extractall(file: str | Path, destdir: str | Path) -> None: - import tarfile + if sys.version_info >= (3, 12): + # Python 3.12 adds a `filter` argument to `TarFile.extractall`, which eliminates + # the security vulnerability in CVE-2007-4559. The `tar_safe_extractall` + # function can be removed once we no longer support Python versions older than + # 3.12. Also, in Python 3.14, "data" will be the default value. + tar.extractall(destdir, filter="data") + else: + import tarfile - destdir = Path(destdir).resolve() + destdir = Path(destdir).resolve() - with tarfile.open(file) as tar: - for member in tar.getmembers(): - member_path = (destdir / member.name).resolve() - if not is_relative_to(member_path, destdir): - raise RuntimeError("Attempted path traversal in tar file.") + with tarfile.open(file) as tar: + for member in tar.getmembers(): + member_path = (destdir / member.name).resolve() + if not is_relative_to(member_path, destdir): + raise RuntimeError("Attempted path traversal in tar file.") - tar.extractall(destdir) + tar.extractall(destdir) # pyright: ignore[reportDeprecated] def print_as_json(x: object) -> None: