GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — shutil.unpack_archive() on Windows writes outside extract_dir for ZIP entries with drive-prefixed names · Issue #146581 · python/cpython

shutil.unpack_archive() on Windows writes outside extract_dir for ZIP entries with drive-prefixed names #146581

New issue
Copy link
New issue
Copy link
Closed
Closed
shutil.unpack_archive() on Windows writes outside extract_dir for ZIP entries with drive-prefixed names#146581
Copy link
Assignees
serhiy-storchaka
Labels
3.10 (EOL)end of lifeend of life3.11only security fixesonly security fixes3.12only security fixesonly security fixes3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesOS-windowsstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-securityA security issueA security issue

Description

@PuH4ck3rX
PuH4ck3rX
opened on Mar 28, 2026
Issue body actions

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_dir is 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

  • gh-146581: Use ZipFile.extractall() in shutil for secure ZIP extraction #146588
  • gh-146581: Fix vulnerability in shutil.unpack_archive() for ZIP files on Windows #146591
  • [3.14] gh-146581: Fix vulnerability in shutil.unpack_archive() for ZIP files on Windows (GH-146591) #149064
  • [3.13] gh-146581: Fix vulnerability in shutil.unpack_archive() for ZIP files on Windows (GH-146591) #149065
  • [3.12] gh-146581: Fix vulnerability in shutil.unpack_archive() for ZIP files on Windows (GH-146591) #149066
  • [3.11] gh-146581: Fix vulnerability in shutil.unpack_archive() for ZIP files on Windows (GH-146591) #149071
  • gh-146581: Update docs for dangerous filenames in ZIP files #149994
  • [3.15] gh-146581: Update docs for dangerous filenames in ZIP files (GH-149994) #150064
  • [3.14] gh-146581: Update docs for dangerous filenames in ZIP files (GH-149994) #150065
  • [3.13] gh-146581: Update docs for dangerous filenames in ZIP files (GH-149994) #150066
  • [3.10] gh-146581: Fix vulnerability in shutil.unpack_archive() for ZIP files on Windows (GH-146591) (GH-149071) #155440

Activity

Next
  1. PuH4ck3rX
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Mar 28, 2026
  2. Shrey-N commented on Mar 29, 2026

    @Shrey-N
    Shrey-N
    on Mar 29, 2026
    Contributor
    More actions

    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_zipfile correctly catches Posix absolute paths and .., but it completely misses Windows drive prefixed paths for example D:/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! :)

  3. StanFromIreland
    assigned
    serhiy-storchaka
    on Mar 29, 2026
  4. picnixz
    added
    type-securityA security issueA security issue
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Mar 29, 2026
  5. picnixz
    added this to Zipfile issues 📦on Mar 29, 2026
  6. picnixz
    added
    OS-windows
    on Mar 29, 2026
  7. serhiy-storchaka commented on Mar 29, 2026

    @serhiy-storchaka
    serhiy-storchaka
    on Mar 29, 2026
    Member
    More actions

    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
  8. StanFromIreland
    added
    3.11only security fixesonly security fixes
    3.10 (EOL)end of lifeend of life
    3.12only security fixesonly security fixes
    3.13only security fixesonly security fixes
    3.14bugs and security fixesbugs and security fixes
    3.15bugs and security fixesbugs and security fixes
    and removed
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Mar 29, 2026
  9. 9 remaining items

  10. serhiy-storchaka
    added 2 commits that reference this issue on May 19, 2026

    [3.13] gh-146581: Update docs for dangerous filenames in ZIP files (G…

    8ee6aff

    [3.15] gh-146581: Update docs for dangerous filenames in ZIP files (G…

    65b2554
  11. StanFromIreland commented on May 19, 2026

    @StanFromIreland
    StanFromIreland
    on May 19, 2026
    Member
    More actions

    @sepastian, you're now a commit co-author :-)

  12. sepastian commented on May 20, 2026

    @sepastian
    sepastian
    on May 20, 2026
    Contributor
    More actions

    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
  13. gaborbernat
    added 2 commits that reference this issue on Jun 3, 2026

    pythongh-150882: Remove unused shutil._ensure_directory

    448cb74

    pythongh-150885: Remove unused shutil._ensure_directory

    5de9387
  14. serhiy-storchaka
    added a commit that references this issue on Jun 7, 2026

    gh-150885: Remove unused shutil._ensure_directory (GH-150883)

    e5ced1f
  15. philthompson10
    added a commit that references this issue on Jun 17, 2026

    pythongh-150885: Remove unused shutil._ensure_directory (pythonGH-150883

    77b5cd3
  16. Yhg1s
    added a commit that references this issue on Aug 4, 2026

    [3.12] gh-146581: Fix vulnerability in shutil.unpack_archive() for ZI…

    a6650a2
  17. pablogsal
    added 2 commits that reference this issue on Aug 9, 2026

    [3.11] gh-146581: Fix vulnerability in shutil.unpack_archive() for ZI…

    7ef7dd0

    [3.10] gh-146581: Fix vulnerability in shutil.unpack_archive() for ZI…

    1071290
  18. StanFromIreland
    closed this as completedon Aug 12, 2026
  19. github-project-automation
    moved this to Done in Zipfile issues 📦on Aug 12, 2026
  20. arnout
    added a commit that references this issue on Aug 14, 2026

    package/python3: security bump to v3.12.14

    80251a0
  21. icanhasmath
    added a commit that references this issue on Oct 28, 2026

    [3.10] pythongh-146581: Fix vulnerability in shutil.unpack_archive() …

    906bb52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @serhiy-storchaka
    serhiy-storchaka

Labels

3.10 (EOL)end of lifeend of life3.11only security fixesonly security fixes3.12only security fixesonly security fixes3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesOS-windowsstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-securityA security issueA security issue

Projects

  • Zipfile issues 📦
    Status
    Done
    Show more project fields

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.