Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessGain local low-privilege account access
-
DeliveryPlant crafted seed-package metadata entries
-
ExploitVictim reseeds into reused destination
-
ExecutionCleanup deletes attacker-named paths
-
ImpactFiles destroyed outside environment root
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V5 - File Handling Path canonicalization, traversal prevention
MITRE ATT&CK
2 techniques across 2 tactics: Discovery, Collection The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires a virtualenv run that reuses a destination already containing distribution metadata influenced by another account, where that metadata's top_level.txt or RECORD entries use relative traversal, absolute paths, or symlinked parent directories pointing outside the environment, AND the invoking user must hold deletion rights over those named paths. The destructive cleanup runs only during environment creation/reseeding before use. Key limiting factors: fresh environments with no pre-existing package metadata are NOT affected, creation with --clear bypasses the vulnerable cleanup path, the attacker needs a prior foothold to plant the metadata (local, low-privilege), and damage is bounded to files the invoking user can already delete. |
| Impact | This is a genuinely low-to-moderate priority issue, not a high-urgency flaw. The CVSS 3.1 vector (AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L, base 4.5 MEDIUM) is internally consistent with the description: exploitation is local, requires low privileges, and carries high attack complexity because the attacker must have already influenced seed-package metadata in a destination that virtualenv later reuses. There is no EPSS score, KEV listing, or POC in the provided data, so exploitation status is 'no public exploit identified at time of analysis' - this is a theoretical/targeted multi-user abuse case rather than a widespread remote threat. The one point worth flagging is impact mapping: the described harm is file DELETION outside the environment, which is an integrity/availability effect; the vendor-supplied vector's C:L (confidentiality) is questionable since no information disclosure is described. Overall the real-world risk is constrained to shared/multi-tenant hosts where one account can seed metadata consumed by another account's virtualenv run. |
| Exploit ScenarioDerived | On a shared host, a lower-trust user plants distribution metadata (top_level.txt or RECORD entries using relative traversal, absolute paths, or symlinked parents) in an app-data seed location or reusable destination. When a higher-value user later creates or reseeds a virtualenv that reuses that destination, virtualenv's PipInstall._uninstall_previous_version() cleanup deletes the attacker-named paths with the invoking user's permissions, destroying files outside the environment. No public exploit code is identified, and the high attack complexity reflects the required pre-positioning of malicious metadata. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 20, 2026
Path traversal in PyPA virtualenv's seed-package cleanup lets a local, low-privileged attacker delete files outside the target environment when a destination directory is reused and already contains distribution metadata planted by another account. Affected are virtualenv releases prior to 21.14.9 that use the embedded app-data seeding path; during environment creation, PipInstall._uninstall_previous_version() trusts top_level.txt and RECORD entries and joins them to site-packages without verifying containment, so relative traversal, absolute paths, or symlinked parent directories reach outside the environment root. Impact is limited to integrity and availability of files the invoking user can already delete (assessed C:N/I:L/A:L), exploitation requires a prior foothold to plant the metadata and a re-run against the same destination, and fresh environments or creation with --clear never enter the vulnerable path; no public exploit code was identified at time of analysis and the issue is not in CISA KEV.
RemediationAI
Vendor-released patch: 21.14.9 - upgrade with 'pip install --upgrade virtualenv>=21.14.9' and pin that floor in any automation or CI images that invoke virtualenv directly (advisory: https://github.com/pypa/virtualenv/security/advisories/GHSA-hhxq-47xx-j5xx; fix commit e3cea6fa10a50fa29cf1fdddd772458fba076d5f). If upgrading is not immediately possible, the most effective compensating control is to create environments in fresh destination directories or with --clear, since both bypass the vulnerable cleanup path entirely - the trade-off is that --clear destroys any existing content in the target directory, so it must not be run against environments that hold uncommitted work. Additionally, ensure shared or cache directories that feed reseeding (virtualenv's app-data cache and any reused destination paths) are not writable by other accounts and are owned by the invoking user, and audit existing .dist-info top_level.txt and RECORD files for '.', absolute paths, or symlinked components before reusing a destination; removing world-writable permissions on those trees prevents the metadata-planting precondition at the cost of breaking multi-user cache sharing. Because damage is bounded to files the invoking user can already delete, running virtualenv as a low-privilege account rather than root limits blast radius, and no confidentiality exposure needs credential rotation.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
virtualenv's bundled 'app-data' seeder installs seed packages (pip, setuptools, wheel) into a per-user application-data cache and then copies or symlinks them into a new environment, which is why a re-used destination may already hold *dist-info metadata left by an earlier run or another account. The vulnerable routine, PipInstall._uninstall_previous_version() -> _uninstall_dist(), read two metadata files inside the existing .dist-info directory: top_level.txt (one top-level package or launcher name per line) and RECORD (relative paths plus hashes). Each name was joined directly to dist.parent (the environment's site-packages) and collected into a path set with no canonicalisation, so '../' sequences, absolute entries, a blank top_level.txt line resolving to site-packages itself, or entries whose parent component is a symlink could all point outside the environment - the code then called safe_delete()/unlink() on whatever resolved. This is CWE-22 (Improper Limitation of a Pathname to a Restricted Directory), here expressed as a deletion primitive rather than a read: the attacker cannot exfiltrate data (no confidentiality impact) but can destroy files the invoking user owns or can delete, before the environment is ever used. The fix in PR #3428 (commit e3cea6fa10a50fa29cf1fdddd772458fba076d5f, released as 21.14.9) resolves the environment root and each candidate entry, skips any entry that is not under root or that is a parent of the metadata directory, warns and continues instead of deleting, and for symlinks resolves only the parent and unlinks the link itself without following it - leaving launcher entries inside the environment and normal reseeding behaviour intact.
Know when Virtualenv gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L
Local metadata-dependent path with multi-user pre-positioning gives AV:L/AC:H/PR:L; impact is file deletion (I:L/A:L) with no disclosure, so C:N.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
2DescriptionCVE.org
virtualenv is a tool for creating isolated virtual python environments. Prior to 21.14.9, PipInstall._uninstall_previous_version() accepts existing seed-package metadata and _uninstall_dist() joins entries from top_level.txt and RECORD to site-packages without checking containment. When a reused destination contains distribution metadata influenced by another account, relative traversal, absolute entries, or linked parents can cause app-data reseeding to delete files outside the environment or the environment root with the invoking user's permissions, provided that user has deletion rights over the named paths. The deletion occurs during environment creation before any later use of the environment. Fresh environments without existing package metadata and creation with --clear do not enter this cleanup path. This issue is fixed in version 21.14.9.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Path traversal exploits occur when applications use user-controlled input to construct file system paths without proper validation.
More in Virtualenv
View allvirtualenv before 20.26.6 allows command injection through the activation scripts for a virtual environment. Rated high
virtualenv versions prior to 21.7.12 cache and seed pip/setuptools wheels without verifying their bytes, so an attacker
Configuration injection in PyPA virtualenv before 21.7.11 lets a line boundary embedded in a prompt value inject extra k
Command injection in PyPA virtualenv before 21.14.9 lets an attacker who controls the destination path of a virtual envi
Command injection in virtualenv's bash activation script prior to 21.14.7 allows a crafted environment name or --prompt
Command injection in the bash, zsh, and fish activation scripts generated by virtualenv releases prior to 21.7.13 lets a
Command injection in PyPA virtualenv before 21.7.12 allows an attacker who controls the environment's prompt value - via
Command injection in virtualenv's bash activator lets an attacker-supplied --prompt value be stored unescaped in PS1 and
Caller-influenced prompt text in virtualenv's bash activation script prior to 21.14.9 can be re-expanded by bash as exec
A code injection flaw in PyPA virtualenv before 21.14.9 lets attacker-influenced non-ASCII characters in the xonsh promp
Symlink following in virtualenv's safe_delete() deletion-error handler (all versions prior to 21.14.9) lets a local atta
Symlink-following file writes in virtualenv before 21.14.9 let a second, unprivileged local account redirect generated e
EUVD-2026-105300
GHSA-hhxq-47xx-j5xx
NVD
CVE.org
EPSS
Exploit-DB