Use tarfile.data_filter for extracting (CVE-2007-4559, PEP-721, PEP-706)

- Require Python with tarfile filters
- Resolves: RHEL-25820
This commit is contained in:
Charalampos Stratakis 2024-04-24 03:26:11 +02:00
parent 3c290026a9
commit 7f0891d88a
2 changed files with 93 additions and 0 deletions

View File

@ -0,0 +1,85 @@
From 1819805f2019c731bcaefd6b12fd814790f88fcd Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Tue, 19 Mar 2024 12:43:07 +0100
Subject: [PATCH] cve-2007-4559-tarfile
Minimal patch for pip
---
src/pip/_internal/utils/unpacking.py | 7 +++++++
src/pip/_vendor/distlib/util.py | 13 +++++++++++++
tests/unit/test_utils_unpacking.py | 17 +++++++++++++++++
3 files changed, 37 insertions(+)
diff --git a/src/pip/_internal/utils/unpacking.py b/src/pip/_internal/utils/unpacking.py
index 5f63f97..c31542f 100644
--- a/src/pip/_internal/utils/unpacking.py
+++ b/src/pip/_internal/utils/unpacking.py
@@ -184,6 +184,13 @@ def untar_file(filename: str, location: str) -> None:
"outside target directory ({})"
)
raise InstallationError(message.format(filename, path, location))
+
+ # Call the `data` filter for its side effect (raising exception)
+ try:
+ tarfile.data_filter(member.replace(name=fn), location)
+ except tarfile.LinkOutsideDestinationError:
+ pass
+
if member.isdir():
ensure_dir(path)
elif member.issym():
diff --git a/src/pip/_vendor/distlib/util.py b/src/pip/_vendor/distlib/util.py
index 80bfc86..7e0941a 100644
--- a/src/pip/_vendor/distlib/util.py
+++ b/src/pip/_vendor/distlib/util.py
@@ -1249,6 +1249,19 @@ def unarchive(archive_filename, dest_dir, format=None, check=True):
for tarinfo in archive.getmembers():
if not isinstance(tarinfo.name, text_type):
tarinfo.name = tarinfo.name.decode('utf-8')
+
+ # Limit extraction of dangerous items, if this Python
+ # allows it easily. If not, just trust the input.
+ # See: https://docs.python.org/3/library/tarfile.html#extraction-filters
+ def extraction_filter(member, path):
+ """Run tarfile.tar_fillter, but raise the expected ValueError"""
+ # This is only called if the current Python has tarfile filters
+ try:
+ return tarfile.tar_filter(member, path)
+ except tarfile.FilterError as exc:
+ raise ValueError(str(exc))
+ archive.extraction_filter = extraction_filter
+
archive.extractall(dest_dir)
finally:
diff --git a/tests/unit/test_utils_unpacking.py b/tests/unit/test_utils_unpacking.py
index ccb7a30..05324ad 100644
--- a/tests/unit/test_utils_unpacking.py
+++ b/tests/unit/test_utils_unpacking.py
@@ -171,6 +171,23 @@ class TestUnpackArchives:
test_tar = self.make_tar_file("test_tar.tar", files)
untar_file(test_tar, self.tempdir)
+ def test_unpack_tar_filter(self) -> None:
+ """
+ Test that the tarfile.data_filter is used to disallow dangerous
+ behaviour (PEP-721)
+ """
+ test_tar = os.path.join(self.tempdir, "test_tar_filter.tar")
+ with tarfile.open(test_tar, "w") as mytar:
+ file_tarinfo = tarfile.TarInfo("bad-link")
+ file_tarinfo.type = tarfile.SYMTYPE
+ file_tarinfo.linkname = "../../../../pwn"
+ mytar.addfile(file_tarinfo, io.BytesIO(b""))
+ with pytest.raises(InstallationError) as e:
+ untar_file(test_tar, self.tempdir)
+
+ assert "is outside the destination" in str(e.value)
+
+
def test_unpack_tar_unicode(tmpdir: Path) -> None:
test_tar = tmpdir / "test.tar"
--
2.44.0

View File

@ -82,6 +82,14 @@ Patch: nowarn-pip._internal.main.patch
# Upstream issue: https://github.com/pypa/packaging/issues/368 # Upstream issue: https://github.com/pypa/packaging/issues/368
Patch: no-version-warning.patch Patch: no-version-warning.patch
# CVE-2007-4559, PEP-721, PEP-706: Use tarfile.data_filter for extracting
# - Minimal downstream-only patch, to be replaced by upstream solution
# proposed in https://github.com/pypa/pip/pull/12214
# - Test patch submitted upstream in the above pull request
# - Patch for vendored distlib, accepted upstream:
# https://github.com/pypa/distlib/pull/201
Patch: cve-2007-4559-tarfile.patch
%description %description
pip is a package management system used to install and manage software packages pip is a package management system used to install and manage software packages
written in Python. Many packages can be found in the Python Package Index written in Python. Many packages can be found in the Python Package Index