On 22 September 2026 Astral released uv 0.12.18, and on 23 September it published advisory GHSA-2cv4-cqwr-gwf7 (CVE-2026-104843). On Windows, uv could be made to write a file outside the installation prefix while installing a wheel. The advisory warns that a malicious wheel could use this to place an executable outside the intended environment, including in a directory already on the user's PATH.
Only Windows hosts are affected. There is no workaround other than upgrading.
What's affected
- Package: uv, distributed on PyPI and as a Rust crate.
- Affected versions: 0.12.7 up to, but not including, 0.12.18.
- Fixed version: 0.12.18 and later. The current release on PyPI at the time of writing is 0.13.1.
- Platforms: Windows only. The advisory says no other platforms are affected.
- Severity: Moderate, CWE-22 (path traversal).
According to PyPI upload dates, 0.12.7 was published on 27 August 2026 and 0.12.18 on 22 September, so the vulnerable window was just under four weeks. The 0.12.18 release notes list two Windows path fixes behind the advisory: rejecting archive entries that normalise to absolute Windows paths, and no longer rebuilding a Windows relative path into an absolute form.
The finder is credited as White0xdi3. Remediation was by woodruffw, reviewed by charliermarsh.
How to check if you're exposed
On each Windows machine and runner that installs Python packages with uv:
uv --version
Then look at how uv gets onto your CI runners, because that's where pinned versions hide:
# GitHub Actions: setup-uv pins and explicit versions
grep -rnE "astral-sh/setup-uv|uv-version|version: ['\"]?0\.12\." .github/workflows/
# Dockerfiles or scripts that pin uv
grep -rnE "uv==0\.12\.|astral.sh/uv/0\.12\." --include=Dockerfile* --include=*.ps1 --include=*.sh .
Exposure needs two things: a vulnerable uv on Windows, and a malicious wheel being installed. Ask which indexes your Windows builds pull from. A private index that mirrors public packages, a --find-links directory anyone can write to, or a direct URL dependency all widen who can supply a wheel.
If you suspect a bad install, look for recently created executables in directories on PATH that don't belong to any installed program:
$env:PATH -split ';' | Where-Object { Test-Path $_ } | ForEach-Object {
Get-ChildItem $_ -Filter *.exe -ErrorAction SilentlyContinue |
Where-Object { $_.CreationTime -gt (Get-Date '2026-08-27') }
} | Select-Object FullName, CreationTime
What to do now
- Upgrade uv to 0.12.18 or later on every Windows workstation and runner:
uv self update # standalone installer pip install -U uv # if installed with pip - Unpin old versions in CI. If your workflows pin a 0.12.x version below 0.12.18, move the pin forward.
- Rebuild Windows images that bake uv in. A golden image built in September may still carry a vulnerable version.
- Restrict where wheels come from. Use a single trusted index, avoid world-writable
--find-linkspaths, and keep a lockfile with hashes so an unexpected wheel fails the install instead of running. - Review installs from the window. If Windows builds installed packages from untrusted or newly added sources between 27 August and your upgrade, check
PATHdirectories for unexpected executables.
Why it matters
Wheel installation is supposed to be the safe half of Python packaging. Unlike source distributions, a wheel has no build step, so installing one should only copy files into the environment. Path traversal breaks that assumption. A wheel that can write outside the prefix can drop a binary where the next shell command will find it, which is code execution without ever running setup.py.
Windows path handling is a recurring source of these bugs because there are so many ways to spell an absolute path: drive letters, UNC prefixes, mixed separators. Archive extractors written and tested mostly on Unix tend to miss some of them. The same class of bug appeared in uv's earlier advisories on tar and ZIP handling, and it is worth assuming it will show up again in other installers.
Try it yourself
List every place your organisation runs uv on Windows: developer laptops, GitHub Actions windows-latest jobs, self-hosted runners and build images. For each, note how uv is installed and whether its version is pinned. Any pinned version without an owner who updates it is the gap this advisory exposes.
Click through it at your own pace, or open it full screen.
Quick check
Your Linux CI runs uv 0.12.10. Do you need to act on CVE-2026-104843?
Not for this advisory. It affects Windows hosts only. Upgrading is still good practice, but Linux runners aren't exposed to this bug.
Is there a configuration workaround if you can't upgrade?
No. The advisory states there is no workaround other than upgrading to uv 0.12.18.
What could a malicious wheel do on a vulnerable Windows host?
Write a file outside the installation prefix, such as an executable placed in a directory already on the user's PATH.