VYPR
Medium severity6.2NVD Advisory· Published Jul 9, 2024· Updated Apr 15, 2026

CVE-2024-5569

CVE-2024-5569

Description

A Denial of Service (DoS) vulnerability exists in the jaraco/zipp library, affecting all versions prior to 3.19.1. The vulnerability is triggered when processing a specially crafted zip file that leads to an infinite loop. This issue also impacts the zipfile module of CPython, as features from the third-party zipp library are later merged into CPython, and the affected code is identical in both projects. The infinite loop can be initiated through the use of functions affecting the Path module in both zipp and zipfile, such as joinpath, the overloaded division operator, and iterdir. Although the infinite loop is not resource exhaustive, it prevents the application from responding. The vulnerability was addressed in version 3.19.1 of jaraco/zipp.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
zippPyPI
< 3.19.13.19.1

Patches

1
fd604bd34f03

Merge pull request #120 from jaraco/bugfix/119-malformed-paths

https://github.com/jaraco/zippJason R. CoombsMay 31, 2024via ghsa
3 files changed · +81 1
  • newsfragments/119.bugfix.rst+1 0 added
    @@ -0,0 +1 @@
    +Improved handling of malformed zip files.
    \ No newline at end of file
    
  • tests/test_path.py+17 0 modified
    @@ -571,3 +571,20 @@ def test_getinfo_missing(self, alpharep):
             zipfile.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 = zipfile.Path(zf)
    +        assert list(map(str, root.iterdir())) == [
    +            'one-slash.txt',
    +            'two-slash.txt',
    +            'parent.txt',
    +        ]
    
  • zipp/__init__.py+63 1 modified
    @@ -86,7 +86,69 @@ def __setstate__(self, state):
             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.
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.