diff --git a/backport-CVE-2024-5569.patch b/backport-CVE-2024-5569.patch new file mode 100644 index 0000000000000000000000000000000000000000..2305924121e88bb62eeb0ea73bb360f6021eaaf7 --- /dev/null +++ b/backport-CVE-2024-5569.patch @@ -0,0 +1,114 @@ +From fd604bd34f0343472521a36da1fbd22e793e14fd Mon Sep 17 00:00:00 2001 +From: "Jason R. Coombs" +Date: Fri, 31 May 2024 12:31:40 -0400 +Subject: [PATCH] Merge pull request #120 from jaraco/bugfix/119-malformed-paths + + Sanitize malformed paths +--- + tests/test_path.py | 17 ++++++++++++ + zipp/__init__.py | 64 +++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 80 insertions(+), 1 deletion(-) + +diff --git a/tests/test_path.py b/tests/test_path.py +index 9504821..0e0ee43 100644 +--- a/tests/test_path.py ++++ b/tests/test_path.py +@@ -582,3 +582,20 @@ class TestPath(unittest.TestCase): + zipp.Path(alpharep) + with self.assertRaises(KeyError): + alpharep.getinfo('does-not-exist') ++ ++ def test_malformed_paths(self): ++ """ ++ Path should handle malformed paths. ++ """ ++ data = io.BytesIO() ++ zf = zipfile.ZipFile(data, "w") ++ zf.writestr("/one-slash.txt", b"content") ++ zf.writestr("//two-slash.txt", b"content") ++ zf.writestr("../parent.txt", b"content") ++ zf.filename = '' ++ root = zipp.Path(zf) ++ assert list(map(str, root.iterdir())) == [ ++ 'one-slash.txt', ++ 'two-slash.txt', ++ 'parent.txt', ++ ] +diff --git a/zipp/__init__.py b/zipp/__init__.py +index 3354c2b..79efbe0 100644 +--- a/zipp/__init__.py ++++ b/zipp/__init__.py +@@ -84,7 +84,69 @@ class InitializedState: + super().__init__(*args, **kwargs) + + +-class CompleteDirs(InitializedState, zipfile.ZipFile): ++class SanitizedNames: ++ """ ++ ZipFile mix-in to ensure names are sanitized. ++ """ ++ ++ def namelist(self): ++ return list(map(self._sanitize, super().namelist())) ++ ++ @staticmethod ++ def _sanitize(name): ++ r""" ++ Ensure a relative path with posix separators and no dot names. ++ ++ Modeled after ++ https://github.com/python/cpython/blob/bcc1be39cb1d04ad9fc0bd1b9193d3972835a57c/Lib/zipfile/__init__.py#L1799-L1813 ++ but provides consistent cross-platform behavior. ++ ++ >>> san = SanitizedNames._sanitize ++ >>> san('/foo/bar') ++ 'foo/bar' ++ >>> san('//foo.txt') ++ 'foo.txt' ++ >>> san('foo/.././bar.txt') ++ 'foo/bar.txt' ++ >>> san('foo../.bar.txt') ++ 'foo../.bar.txt' ++ >>> san('\\foo\\bar.txt') ++ 'foo/bar.txt' ++ >>> san('D:\\foo.txt') ++ 'D/foo.txt' ++ >>> san('\\\\server\\share\\file.txt') ++ 'server/share/file.txt' ++ >>> san('\\\\?\\GLOBALROOT\\Volume3') ++ '?/GLOBALROOT/Volume3' ++ >>> san('\\\\.\\PhysicalDrive1\\root') ++ 'PhysicalDrive1/root' ++ ++ Retain any trailing slash. ++ >>> san('abc/') ++ 'abc/' ++ ++ Raises a ValueError if the result is empty. ++ >>> san('../..') ++ Traceback (most recent call last): ++ ... ++ ValueError: Empty filename ++ """ ++ ++ def allowed(part): ++ return part and part not in {'..', '.'} ++ ++ # Remove the drive letter. ++ # Don't use ntpath.splitdrive, because that also strips UNC paths ++ bare = re.sub('^([A-Z]):', r'\1', name, flags=re.IGNORECASE) ++ clean = bare.replace('\\', '/') ++ parts = clean.split('/') ++ joined = '/'.join(filter(allowed, parts)) ++ if not joined: ++ raise ValueError("Empty filename") ++ return joined + '/' * name.endswith('/') ++ ++ ++class CompleteDirs(InitializedState, SanitizedNames, zipfile.ZipFile): + """ + A ZipFile subclass that ensures that implied directories + are always included in the namelist. +-- +2.45.2 + diff --git a/python-zipp.spec b/python-zipp.spec index 99f9aff0856502c572b580e37d06a8243e057153..74125fcdc26c31f4049db121f367f842e0231a2e 100644 --- a/python-zipp.spec +++ b/python-zipp.spec @@ -1,11 +1,13 @@ %global _empty_manifest_terminate_build 0 Name: python-zipp Version: 3.17.0 -Release: 1 +Release: 2 Summary: Backport of pathlib-compatible object wrapper for zip files License: MIT URL: https://github.com/jaraco/zipp Source0: https://pypi.io/packages/source/z/zipp/zipp-%{version}.tar.gz +# https://github.com/jaraco/zipp/commit/fd604bd34f0343472521a36da1fbd22e793e14fd +Patch3000: backport-CVE-2024-5569.patch BuildArch: noarch %description @@ -35,7 +37,7 @@ Provides: python3-zipp-doc A pathlib-compatible Zipfile object wrapper. A backport of the Path object. %prep -%autosetup -n zipp-%{version} +%autosetup -n zipp-%{version} -p1 # Skip tests that depend on jaraco.itertools sed -i "/import jaraco.itertools/d" tests/test_path.py @@ -65,6 +67,9 @@ pytest -k "not test_joinpath_constant_time" %{_docdir}/* %changelog +* Mon Jul 22 2024 yaoxin - 3.17.0-2 +- Fix CVE-2024-5569 + * Mon Sep 11 2023 xu_ping <707078654@qq.com> - 3.17.0-1 - Upgrade version to 3.17.0