Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessInfluence venv destination path or --prompt
-
ExploitEmbed placeholder token with quote-breaking payload
-
ExecutionVictim activates environment via bash/fish/xonsh
-
ImpactInjected commands execute arbitrarily
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization OS command sanitization, avoid shell exec
MITRE ATT&CK
2 techniques across 1 tactic: Execution The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires the attacker to control or influence the virtualenv's destination path OR the --prompt value, and that value must literally contain one of the trigger placeholder names (__VIRTUAL_NAME__, __VIRTUAL_ENV__, or __VIRTUAL_PROMPT__); a value without a relevant placeholder does not trigger the mechanism. The payload only yields command execution when the victim subsequently activates the environment through bash, fish, xonsh, or via activate_this.py. Limiting factors: user interaction is mandatory (someone must activate the environment), the attacker must have a way to supply the path/prompt (typically only in automation, multi-user, or tooling scenarios - not a normal self-created venv), and the affected version window is 20.26.6 through <21.14.2. The csh-specific token __VIRTUAL_PROMPT_DISPLAY_TCSH__ only breaks the generated script and does NOT achieve command execution, so csh is not a code-execution vector. |
| Impact | CVSS is 7.8 (HIGH) with vector CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H, indicating a local attack of low complexity that requires no attacker privileges but does require victim interaction (activating the environment), yielding full confidentiality/integrity/availability impact via command execution (CWE-78). No EPSS score was provided in the input, so exploitation probability cannot be quantified. The vulnerability is NOT in CISA KEV and no public exploit was identified, so this is 'no public exploit identified at time of analysis' - note, however, that the fix commit ships adversarial unit tests (e.g. a path 'A__VIRTUAL_NAME__B/x'\$(touch PWNED)'y') that function as a working proof-of-concept of the technique, even if a packaged public exploit is not cataloged here. On balance this is a genuine but conditional flaw rather than a drop-everything emergency: the AV:L vector plus the mandatory preconditions (attacker must influence the destination path or --prompt, that value must contain a trigger placeholder, and a victim must activate the env in bash/fish/xonsh or import activate_this.py) make it non-wormable and non-mass-exploitable, unlike a network-facing RCE. The elevated score is driven by the H/H/H impact, not by ease of large-scale exploitation; realistic targeting is narrow (e.g. CI/automation or tooling that creates venvs at externally supplied paths). |
| Exploit ScenarioDerived | An attacker who can influence where a victim's virtualenv is created (for example automation or a shared workflow that builds a venv at a caller-supplied path) or the --prompt value embeds a template placeholder such as __VIRTUAL_NAME__ alongside a quote-breaking payload in the path/prompt. Because instantiate_template() substitutes placeholders one key at a time, a later pass rewrites that token inside the already-quoted path, closing the literal so that when the victim activates the environment under bash, fish, xonsh, or activate_this.py the remaining payload executes as arbitrary commands. No packaged public exploit is cataloged, but the vendor's fix commit includes a 'touch PWNED' proof-of-concept test demonstrating the technique. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 21, 2026
OS command injection in virtualenv 20.26.6 through 21.14.2 lets an attacker who controls the environment's destination path or the --prompt value smuggle shell metacharacters into generated activation scripts. Because the template engine substitutes placeholders one key at a time over the whole template, a path or prompt containing the literal text __VIRTUAL_NAME__, __VIRTUAL_ENV__, or __VIRTUAL_PROMPT__ gets rewritten again during a later pass, and the later value's quoting can close the earlier literal and execute the remaining path when a victim activates the environment with bash, fish, xonsh, or activate_this.py. Per the CVSS vector CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H this is a local, low-complexity issue requiring no attacker privileges but mandatory victim interaction, yielding full confidentiality, integrity, and availability impact; no public exploit code or CISA KEV entry was identified at time of analysis, and the vendor-released fix is version 21.14.2.
RemediationAI
Vendor-released patch: 21.14.2. Upgrade with pip install --upgrade "virtualenv>=21.14.2" (or pin the same floor in build tooling and CI images) and then regenerate existing activation scripts by recreating or re-running the relevant virtualenv invocations - pre-existing activate scripts rendered by an affected version remain poisoned until regenerated. Audit automation, wrappers, and CI jobs that pass externally supplied destination paths or --prompt values, since those are the only realistic injection channels; treat any path or prompt containing __VIRTUAL_NAME__, __VIRTUAL_ENV__, or __VIRTUAL_PROMPT__ as hostile until the upgrade lands. As an interim compensating control, sanitize or reject path and prompt inputs that contain double-underscore placeholder tokens before invoking virtualenv (side effect: legitimate directory names containing those tokens are refused), and avoid activating environments whose creation path was attacker-influenced (side effect: operational friction in multi-user or shared-workspace setups). There is no configuration switch that disables the vulnerable substitution pass, so the version upgrade is the only complete fix. csh users can treat the __VIRTUAL_PROMPT_DISPLAY_TCSH__ symptom as script corruption only - it does not yield command execution - but should still upgrade for correctness. Detection: grep generated bin/activate, activate.fish, activate.xonsh, and activate_this.py files for the placeholder tokens followed by quoting anomalies or shell metacharacters, and review creation logs for paths or prompts containing those tokens.
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 renders per-shell activation scripts through ViaTemplateActivator, historically by iterating the replacements dictionary and calling text.replace(key, quote(value)) for each placeholder in turn. That multi-pass design violates a core templating invariant: substituted data is re-scanned as template syntax. If a user-controlled value - the venv destination path or --prompt - literally embeds a placeholder name such as __VIRTUAL_NAME__, __VIRTUAL_ENV__, or __VIRTUAL_PROMPT__, that embedded token is expanded during a subsequent pass. The injected expansion is quoted for a later context, so its quoting can terminate the earlier quoted literal and leave the remainder as live shell syntax in the generated activate script (CWE-78, improper neutralization of special elements used in an OS command). The upstream commit 602b26623a724827ff171bf11fef4ad186d01f74 fixes the class of bug rather than the instance: it compiles a single regular-expression alternation over the replacement keys (sorted longest-first to avoid prefix shadowing) and performs one pass with pattern.sub(), so a placeholder name occurring inside an already-quoted value stays inert data. It also refactors the csh activator to implement a substitutions() hook instead of post-processing the rendered text, and rewrites tests to assert that paths such as A__VIRTUAL_NAME__B/x'$(touch PWNED)'y and csh prompts containing __VIRTUAL_PROMPT_DISPLAY_TCSH__ are handled safely. Note the asymmetry confirmed by the patch and assessment: the csh-only display token __VIRTUAL_PROMPT_DISPLAY_TCSH__ merely corrupts the generated script rather than achieving command execution, so csh is not a code-execution vector; bash, fish, xonsh, and activate_this.py are.
Know when Python 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:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Local because the env must be created/activated on the host (AV:L); attacker needs no privileges, only control of the path/prompt (PR:N); victim must activate the env (UI:R); command execution gives C:H/I:H/A:H.
Primary rating from Vendor (github).
CVSS VectorVendor: github
Lifecycle Timeline
2DescriptionCVE.org
virtualenv is a tool for creating isolated virtual python environments. From 20.26.6 until 21.14.2, ViaTemplateActivator.instantiate_template() replaces placeholders one key at a time across the complete activation template, so trigger names such as __VIRTUAL_NAME__, __VIRTUAL_ENV__, or __VIRTUAL_PROMPT__ inside an already substituted and quoted environment path or prompt can be replaced during a later pass. The later value's quoting can close the earlier literal and execute the remaining path when a user activates the environment through bash, fish, xonsh, or activate_this.py. The distinct csh prompt-display token __VIRTUAL_PROMPT_DISPLAY_TCSH__ can instead break the generated script without establishing command execution. The attacker must influence the destination path or --prompt, and a value without a relevant placeholder name does not trigger this mechanism. This issue is fixed in version 21.14.2.
Blast Radius
ecosystem impact- 6 pypi packages depend on virtualenv (6 direct, 0 indirect)
Ecosystem-wide dependent count for version 20.26.6.
Technical POC Analysis
CWE-78 (OS command injection; the advisory also tags CWE-94) in ViaTemplateActivator.instantiatetemplate() in virtualenv's activation-template renderer.
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Executive ViewAI
A flaw in the widely used Python packaging tool virtualenv (versions 20.26.6 through 21.14.2) allows shell commands to be hidden inside the activation scripts generated for a virtual environment, so that the commands run on a developer's machine the moment that environment is activated. Exploitation requires a victim to activate a crafted environment, but no attacker privileges are needed, and a successful hit gives full control over confidentiality, integrity, and availability of that workstation. Because virtualenv is embedded across developer laptops, CI runners, and build images, leadership should treat this as a developer-endpoint and software-supply-chain exposure rather than a niche tooling issue.
Apply vendor patch.
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
OS command injection occurs when an application passes unsanitized user input directly into system shell commands.
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
EUVD-2026-106868
GHSA-8rjx-v5ww-45pp
NVD
CVE.org
EPSS
Exploit-DB