GHSA-pjjw-68hj-v9mw
Medium · 4.3uv vulnerable to arbitrary file deletion through RECORD entries
CVSS
4.3
EPSS
—
Published
Apr 10, 2026
CISA due date
—
Cloudanix analysis
A malicious Python package can trick older uv versions into deleting files outside the package when it is later removed.
- Exploitation
- Requires User Interaction
- Attacker needs
- User Interaction
- Complexity
- Moderate
- Impact
- Data Tampering
- Component
- Application
- Class
- Path Traversal
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
uv versions 0.11.5 and earlier fail to reject wheel metadata where the `.dist-info/RECORD` file contains relative paths that traverse outside the wheel installation prefix, such as `../` path components. uv uses `RECORD` entries during uninstall to decide which files to remove. A maliciously crafted Python wheel can therefore cause uv to delete files outside the installed package directory when the package is uninstalled. The flaw does not allow arbitrary file creation or modification during installation, and absolute paths are treated as relative to the installation prefix, so the primary impact is arbitrary file deletion constrained by the permissions of the user running uninstall. Exploitation requires both installation and later uninstallation of the malformed wheel, and the attacker must craft traversal paths that correctly account for the installation directory depth.
Why it matters to the business
This issue can cause accidental or attacker-induced deletion of application, virtual environment, user, or system files when a malicious Python package is uninstalled with an affected uv version. The most likely business impact is service disruption, broken builds, corrupted developer environments, failed deployments, or loss of local files. Because exploitation requires a specially crafted wheel and an uninstall action, and because there is no known KEV listing or ransomware association, urgency is moderate rather than emergency; however, organizations that install packages from untrusted indexes, internal mirrors, CI/CD pipelines, or third-party artifacts should prioritize remediation to prevent supply-chain-triggered disruption.
How an attack unfolds
An attacker creates or modifies a Python wheel so that its `.dist-info/RECORD` file includes relative traversal entries pointing outside the package installation prefix. The wheel otherwise appears installable and may be distributed through a package index, dependency confusion route, compromised artifact repository, direct download, or internal supply-chain channel. A user, build job, or automation process installs the wheel with uv 0.11.5 or earlier. Installation does not use the malicious `RECORD` paths to place files outside the prefix, so the issue may remain dormant. Later, when the package is uninstalled, uv trusts the invalid `RECORD` entries and attempts to remove the listed files. If the traversal depth and target filenames match real files and the uninstalling user has permission to delete them, those files are removed, potentially damaging applications, environments, or system state.
How to fix it
Upgrade uv to a version newer than 0.11.5 that rejects or safely handles invalid wheel `RECORD` path entries. If package-level fixed versions are maintained internally, require the fixed uv version in developer workstations, build images, CI runners, container base images, and dependency management tooling. Until upgraded, avoid uninstalling packages installed from untrusted or manually built wheels with affected uv versions. Prefer trusted package indexes, verified artifact provenance, pinned dependencies, hash-checked installs, and isolated disposable virtual environments for untrusted packages. Remove or quarantine any wheel whose `.dist-info/RECORD` contains parent-directory traversal such as `../` or `..\`. For high-risk environments, rebuild virtual environments rather than uninstalling suspicious packages in place.
How to confirm the fix worked
Confirm that `uv --version` reports a version later than 0.11.5 on developer endpoints, CI/CD runners, build containers, and automation images. Test package handling by attempting to install or process a benign test wheel with a `RECORD` entry containing parent-directory traversal and verify that the fixed uv version rejects it or does not honor the invalid path during uninstall. Inventory installed distributions and cached wheel artifacts for `.dist-info/RECORD` entries containing `../` or `..\`. Review CI images and lockfiles to ensure the vulnerable uv binary is not reintroduced by base image rebuilds or bootstrap scripts.
Typical attack path
- Craft a Python wheel with a manipulated `.dist-info/RECORD` file containing relative path traversal entries such as `../../../target-file`.
- Distribute the wheel through a package index, artifact repository, dependency confusion package name, phishing link, compromised project, or internal build dependency path.
- Wait for a developer, CI/CD job, or automation process using uv 0.11.5 or earlier to install the wheel.
- Rely on the malicious metadata remaining present after installation without obvious runtime symptoms.
- Trigger or wait for package uninstall, environment cleanup, dependency replacement, or build teardown using the affected uv version.
- During uninstall, uv reads the invalid `RECORD` entries and deletes files outside the package installation prefix if the paths resolve to existing files and permissions allow removal.
How to detect it
To determine whether this was already exploited, review package installation and uninstall activity from developer endpoints, CI/CD systems, build logs, shell histories, container build logs, and artifact repository access logs. Focus on cases where uv 0.11.5 or earlier installed and later uninstalled the same wheel or package, especially from untrusted, newly introduced, direct URL, or internal mirror sources. Inspect installed package metadata, wheel caches, artifact repositories, and preserved build workspaces for `.dist-info/RECORD` files containing parent-directory traversal. Correlate suspicious uninstall events with unexpected file deletion errors, missing configuration files, broken virtual environments, failed builds, or file integrity monitoring alerts. If available, compare filesystem snapshots or backups before and after package uninstall operations to identify deleted files outside the package prefix. There are no known public threat actors or KEV exploitation reports associated with this advisory, so detection should be behavior- and artifact-focused rather than actor-specific.
- .dist-info/RECORD
- ../
- ..\\
- /RECORD:../
- /RECORD:..\\
- uv pip uninstall
- uv pip install
- uv uninstall
- Deleting file outside package prefix
- RECORD contains relative path traversal
- ../../../
- ..\/..\/
- site-packages/*.dist-info/RECORD
What your security team should do
- Prioritize upgrading uv wherever it is used for Python package installation, especially in CI/CD, release engineering, developer workstations, and build containers.
- Search artifact repositories, package caches, source trees, and installed environments for wheel `RECORD` files containing `../` or `..\` traversal entries.
- Treat any package with malformed `RECORD` traversal entries as suspicious unless there is a documented benign test purpose; quarantine the artifact and investigate its source.
- Avoid uninstalling suspicious packages with uv 0.11.5 or earlier; preserve evidence first, then rebuild the environment from trusted inputs.
- Enforce package provenance controls such as approved indexes, dependency pinning, hash verification, signed artifacts where available, and restrictions on direct wheel installation from untrusted sources.
- Add CI checks that inspect wheels before publication or installation and fail builds when `.dist-info/RECORD` contains absolute paths, parent-directory traversal, or non-normalized paths.
- Monitor for unexpected file deletion or environment corruption following Python package uninstall operations, particularly in automation jobs that recently installed third-party wheels.
The record
Wheel RECORD entries can contain relative paths that traverse outside of the wheel’s installation prefix. In versions 0.11.5 and earlier of uv, these wheels were not rejected on installation and the RECORD was respected without validation on uninstall. uv uses the RECORD to determine files to remove on uninstall. Consequently, a malicious or malformed wheel could induce deletion of arbitrary files outside of the wheel’s installation prefix on uninstall. uv does not use the RECORD file to determine wheel file paths. Invalid RECORD entries cannot be used to create or modify files in arbitrary locations. Standards-compliant Python packaging tooling does not produce RECORD files that exhibit this behavior; an attacker must manually manipulate the RECORD. A user must install *and* uninstall the malformed wheel to be affected. An attack must guess the depth of the installation prefix path in order to target system files. Absolute paths in RECORD files are not allowed by the specification and, when present, uv always treats them as rooted in the wheel’s installation prefix. Absolute paths cannot be used to delete arbitrary files. Only files can be deleted, attempts to delete a directory via an invalid RECORD entry will fail.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|
Related vulnerabilities
- CVE-2026-81163 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')… CWE-22
- CVE-2026-112049 Vita3K before build 4187 contains a path traversal (zip slip) vulnerability in… CWE-22
- CVE-2026-112005 WhoDB 0.104.0 before 0.135.0 contains a path traversal vulnerability that allows remote… CWE-22
- CVE-2026-61702 OpenPrinting CUPS is an open source printing system for Linux and other Unix-like… CWE-22
- CVE-2026-104871 The Angular SSR is a server-rise rendering tool for Angular applications. CWE-22
- CVE-2026-102991 Mako is a template library written in Python. CWE-22
- CVE-2026-101894 The decompress package for Node.js extracts archives. CWE-22
- CVE-2026-100689 GitPython before 3.1.62 does not validate the `path` field read from an untrusted… CWE-22