shutil.unpack_archive() on Windows writes outside extract_dir for ZIP entries with drive-prefixed names #146581
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Mar 28, 2026 Hiya @PuH4ck3rX I have investigated this and can confirm I was able to reproduce the bug locally on Windows.
The current sanitization in
shutil._unpack_zipfilecorrectly catches Posix absolute paths and.., but it completely misses Windows drive prefixed paths for exampleD:/file.txt, which allows the directory traversal.I am working on a fix now and will try to submit a Pull Request ASAP!
Thank you for the bug report! :)
- addedtype-securityA security issueA security issuestdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Mar 29, 2026 Sorry, this was discussed privately, and solution was created a month ago. Three days ago I asked for opening a public issue, so the solution also can be made public. See #146591.
Reacted by Stan Ulbrych and Bird- added3.11only security fixesonly security fixes3.10 (EOL)end of lifeend of life3.12only security fixesonly security fixes3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesand removedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Mar 29, 2026 8 remaining items
- added 3 commits that reference this issue
on May 19, 2026 @sepastian, you're now a commit co-author :-)
Thank you very much @StanFromIreland and @serhiy-storchaka and everyone else involved!
Sorry for the noise and thanks again for all your great work on this!
🙏🏼
Reacted by Zachary Ware and Stan Ulbrych- added a commit that references this issue
on Aug 4, 2026 - added a commit that references this issue
on Aug 14, 2026
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDone
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 asD:/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_diron Windows.Trigger condition
D:/...extract_diris on a different driveTested 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.pyThe 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