-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
Description
Bug report
Bug description:
Summary
I found a Windows-specific issue in shutil.unpack_archive() when extracting ZIP files.
In Lib/shutil.py, the private helper _unpack_zipfile() skips names that start with / or contain .., but it does not reject or sanitize Windows drive-prefixed names such as D:/path/file.
On Windows, such names are joined into a drive-qualified path and can escape the intended extraction directory. As a result, a crafted ZIP archive can cause files to be written outside extract_dir.
Affected component
Lib/shutil.py_unpack_zipfile()
Impact
A crafted ZIP archive can cause an arbitrary file write outside extract_dir on Windows.
Trigger condition
- Platform: Windows
- Archive format: ZIP
- A ZIP entry name contains a drive prefix such as
D:/... extract_diris on a different drive
Tested environment
I reproduced this on Windows with Python 3.12.8.
Minimal reproduction
I attached a minimal repro script:
repro_shutil_unpack_zip_windows_drive_path_min.py
The repro creates a ZIP archive containing an entry like:
D:/shutil_outside_min.txt
and then calls:
shutil.unpack_archive(str(zip_path), str(extract_dir))
With extract_dir on another drive, the file is written outside the intended extraction directory.
Root cause
The validation in _unpack_zipfile() appears incomplete for Windows path semantics. Checking only for leading / and .. is not sufficient, because drive-prefixed paths such as D:/... are still treated as rooted or drive-qualified paths by Windows path handling.
For comparison, zipfile's own extraction logic strips drive information before extraction, but shutil._unpack_zipfile() does not.
Expected behavior
ZIP entries that are absolute, drive-prefixed, or otherwise resolve outside extract_dir on Windows should be rejected or normalized so that extraction always remains within extract_dir.
Actual behavior
A crafted ZIP entry with a drive prefix can escape extract_dir and be written to another location.
Additional context
I previously reported this privately to the Python Security Response Team on March 28, 2026, but I have not received a response yet, so I am opening this issue for tracking and triage.
I also attached a short write-up:
vuln_shutil_unpack_archive_zip_windows_drive_path.md
shutil_unpack_archive_zip_windows_drive_path_min.zip
CPython versions tested on:
CPython main branch, 3.14
Operating systems tested on:
Windows
Linked PRs
Metadata
Metadata
Assignees
Labels
Projects
Status