Skip to main content

virtualenv CVE-2026-102930

| EUVDEUVD-2026-89462 HIGH
Download of Code Without Integrity Check (CWE-494)
2026-09-29 GitHub_M GHSA-94p9-xgh2-xp45
7.7
CVSS 4.0 · Vendor: GitHub_M
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Compromise index or MITM PyPI TLS
  2. Delivery
    Serve malicious wheel with matching name/version/filename
  3. Exploit
    User runs virtualenv seed/download on default index
  4. Execution
    Unverified wheel cached and seeded
  5. Impact
    Attacker code runs in created environments

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A08:2025 - Software or Data Integrity Failures
ASVS 5.0
V15 - Secure Coding and Architecture Code integrity verification
Exploitation Conditions

Exploitation requires all of: (1) the attacker occupies the wheel delivery path - a compromised package index, a stale/poisoned mirror, or an intercepted TLS connection to PyPI (AC:H/AT:P); (2) virtualenv fetches seed wheels via a periodic update or the --download option; (3) the environment uses the DEFAULT PyPI path - the digest check (and thus this fix) is intentionally skipped when PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, or PIP_INDEX is set, and a pip.conf custom index is invisible to the check entirely; and (4) a user actually creates/seeds a virtual environment (UI:P). Limiting factors: affected virtualenv versions prior to 21.7.12, the need for an active MITM or index/mirror compromise, and required user action. Note that even after patching, custom-index configurations remain unverified by design.

Impact

This is a genuine supply-chain integrity flaw but not a top-tier emergency. The vendor CVSS 4.0 vector (AV:N/AC:H/AT:P/PR:N/UI:P) shows the two features that temper the 7.7 score: AC:H and AT:P mean the attacker must already control the delivery path (compromise the index, poison a mirror, or actively MITM the TLS connection to PyPI), and UI:P means a user must actually create/seed a virtual environment. There is no EPSS score, no CISA KEV listing, and no public exploit identified at time of analysis, so this is a latent risk rather than one under active mass exploitation. The impact if the preconditions are met is severe (VC:H/VI:H/VA:H - attacker-controlled pip/setuptools wheels seeded into every subsequently created environment, i.e. code execution), which justifies treating it as a real priority for organizations that pull seed wheels over untrusted networks or through mirrors. Note the CWE and the vendor 'Information Disclosure' tag conflict: this is CWE-494 (download of code without integrity check) with integrity/availability impact, not an information-disclosure bug. The verification fix also only applies to the default PyPI path and is deliberately skipped for custom indexes, so environments using PIP_INDEX_URL/pip.conf remain unverified by design - a limitation defenders should understand.

Exploit ScenarioDerived

An attacker who controls a corporate PyPI mirror, a poisoned package index, or a position to MITM the TLS connection substitutes a malicious pip or setuptools wheel that keeps the requested distribution name, version, and filename. When a developer or CI job runs virtualenv against the default PyPI index (periodic seed update or --download), the unverified wheel is cached and seeded into every new environment, executing attacker code. No public PoC is known, and the attack requires both an active man-in-the-middle/index-compromise position (AC:H/AT:P) and a user creating an environment (UI:P).

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
1 public PoC Patch available 0.2% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Sep 29, 2026

virtualenv versions prior to 21.7.12 cache and seed pip/setuptools wheels without verifying their bytes, so an attacker who controls the wheel delivery path can substitute a different wheel under the requested distribution, version, and filename and have it injected into every environment virtualenv subsequently creates. The flaw is exploitable unauthenticated but requires an active man-in-the-middle position, a compromised index, or a stale/poisoned mirror, and requires a user to actually create or seed a virtual environment. No public exploit code was identified at time of analysis, and the digest check is intentionally skipped whenever PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, or PIP_INDEX points at a custom index - meaning custom-index users remain unverified even after upgrading.

RemediationAI

Upgrade to virtualenv 21.7.12 or later (vendor-released patch: 21.7.12), which enables SHA-256 verification of downloaded seed wheels against PyPI's published release digests before they are cached or seeded - see the advisory at https://github.com/pypa/virtualenv/security/advisories/GHSA-94p9-xgh2-xp45 and the fix in PR #3251 / commit a01ed3e2f239d6ab1fce62c5c7664ccf268fff6d. Because the check is deliberately bypassed when PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, or PIP_INDEX is set (and is blind to a pip.conf-defined index), operators who rely on a private or internal index get no digest protection even on 21.7.12 and must enforce integrity at the index layer: serve seed wheels only over TLS with certificate validation, mirror PyPI artifacts by hash rather than accepting at re-upload time, and monitor for rebuilt wheels published under upstream filenames - the trade-off is that mirror re-packaging workflows must now maintain their own trusted digest manifest. Environments that can tolerate it should clear the PIP_INDEX* variables before running virtualenv so the default index path (and its verification) is used, at the cost of losing access to internal packages. As a compensating control, disable periodic seed-wheel updates and avoid the --download option where possible, or pre-seed environments from a hash-verified local wheel bundle, accepting the operational overhead of manual wheel curation. Finally, treat environments created with affected versions as potentially contaminated: identify cached wheels in the virtualenv app-data seed cache and re-create affected environments after patching.

Affected VersionsENISA

virtualenv < 21.7.12

Affected Packages

pypi virtualenv fix: 21.7.12

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

The root cause is CWE-494 (Download of Code Without Integrity Check): virtualenv's download_wheel() in src/virtualenv/seed/wheels/acquire.py shelled out to pip download, which trusts whatever index it is configured to use, and then cached and seeded the returned artifact with no validation of its contents. This contrasts with virtualenv's own embedded seed wheels, which are already covered by an internal BUNDLE_SHA256 verification. The upstream fix (PR #3251, commit a01ed3e2f239d6ab1fce62c5c7664ccf268fff6d) adds verify_wheel_digest() in periodic_update.py, which queries PyPI's JSON API release metadata, finds the entry whose filename matches the downloaded wheel, computes the file's SHA-256 locally, and raises RuntimeError on mismatch - a fatal error that guarantees the wheel is never cached or seeded. A missing PyPI release record or absent sha256 field only logs a debug message and lets the wheel through, since the artifact may legitimately come from a private index PyPI has never seen. The fix also gates the check behind _uses_default_index(), which returns False when any of PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, or PIP_INDEX is set in the environment; the code comments explicitly acknowledge that a pip.conf-defined custom index has the same effect but is invisible to this check, so the authors describe the guard as a conservative false-rejection-avoidance signal rather than proof that verification ran when it safely could have.

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

Vendor (GitHub_M) PRIMARY 7.7 HIGH
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
vuln.today AI 7.5 HIGH

AC:H because the attacker must control the index/mirror or MITM the download; UI:R since a user must create/seed an environment; C/I/A:H as attacker wheels execute code in created environments.

3.1 AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H
4.0 AV:N/AC:H/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Red Hat 7.5 HIGH

Primary rating from Vendor (GitHub_M).

CVSS VectorVendor: GitHub_M

Attack Vector
Network
Attack Complexity
High
Attack Requirements
Present
Privileges Required
None
User Interaction
Passive
Vulnerable system: Confidentiality
High
Vulnerable system: Integrity
High
Vulnerable system: Availability
High
Subsequent system: Confidentiality
None
Subsequent system: Integrity
None
Subsequent system: Availability
None

Lifecycle Timeline

2
Patch available
Sep 29, 2026 - 22:19 EUVD
CVE Published
Sep 29, 2026 - 20:53 cve.org
HIGH 7.7

DescriptionCVE.org

virtualenv is a tool for creating isolated virtual python environments. Prior to 21.7.12, download_wheel() accepts pip and setuptools seed wheels fetched for periodic updates or the --download option without checking their bytes against an authoritative digest equivalent to the embedded wheels' BUNDLE_SHA256 verification. A compromised index, stale mirror, or intercepted TLS connection can substitute a different wheel under the requested distribution, version, and filename, after which virtualenv caches and seeds the attacker-controlled wheel into subsequently created environments. The verification applies to the default PyPI path and is intentionally skipped when PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, or PIP_INDEX configures a custom index that may legitimately publish rebuilt wheels. This issue is fixed in version 21.7.12.

Technical POC Analysis

The flaw is CWE-494 (Download of Code Without Integrity Check) in virtualenv's downloadwheel().

Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.

Latest POC

1 public PoC link from github

Sign in to open the public PoC links collected for this CVE.

Executive ViewAI

Why It Matters

virtualenv versions prior to 21.7.12 can inject attacker-supplied pip/setuptools wheels into every subsequently created Python environment when an adversary controls the wheel delivery path, creating a supply-chain risk across development, build, and CI/CD pipelines. No public exploit identified at time of analysis, and no vendor-released patch identified at time of analysis. Leadership should prioritize this due to the broad blast radius and the potential for malicious code execution in many downstream environments.

Business Impact: High
Compensating Controls

No vendor-released patch identified at time of analysis. Interim mitigations: avoid custom package indexes (PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, PIP_INDEX) because digest checks are intentionally skipped for them; use virtualenv --no-seed where possible to prevent seeding of pip/setuptools wheels; restrict and monitor network paths to package indexes and wheel caches to prevent man-in-the-middle or poisoned-mirror substitution; enforce TLS certificate validation and DNS security; use an internal, immutable mirror with manual SHA256 verification of all pip/setuptools wheels before caching or seeding; and monitor for unexpected wheel changes or suspicious index configurations in CI/CD pipelines.

Threat Intelligence Overview

EPSS Score
0.2%
Top 96% exploitable
Prevalence
Ubiquitous
virtualenv is a foundational, near-universal Python environment tool in dev/CI
Threat Intel
1
1 sources
Data Quality
7 sources
Confidence: High
EUVD NVD CVE.org EPSS Vulnrichment GHSA MSRC Vendor GitHub

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.

SignalValue
Severity HIGH
CISA KEV No
Public POC Yes
EPSS 0.2%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
None
System Exposure· derived
Open
Automatable
No
Human Impact
High
Technical Impact
Total

Priority Score

58
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +38
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy