Skip to main content

virtualenv CVE-2026-113776

| EUVDEUVD-2026-106868 HIGH
OS Command Injection (CWE-78)
2026-10-20 security-advisories@github.com GHSA-8rjx-v5ww-45pp
7.8
CVSS 3.1 · Vendor: github
View

Attack ChainAIDerived

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

  1. Access
    Influence venv destination path or --prompt
  2. Exploit
    Embed placeholder token with quote-breaking payload
  3. Execution
    Victim activates environment via bash/fish/xonsh
  4. Impact
    Injected 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.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
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 – 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

virtualenv 20.26.6, < 21.14.2

Affected Packages

pypi virtualenv fix: 21.14.2

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

Vendor (github) PRIMARY 7.8 HIGH
AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
vuln.today AI 7.8 HIGH

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.

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

Primary rating from Vendor (github).

CVSS VectorVendor: github

Attack Vector
Local
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

2
Patch available
Oct 20, 2026 - 23:20 EUVD
CVE Published
Oct 20, 2026 - 22:19 cve.org
HIGH 7.8

DescriptionCVE.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.

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

Why It Matters

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.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.2%
Top 85% exploitable
Prevalence
High
one of the most-used Python virtual-environment tools, pervasive in dev and CI
Threat Intel
1
1 source
Data Quality
6 sources
Confidence: High

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 No
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· derived
Defer
Exploitation· derived
None
System Exposure· derived
Small
Automatable· derived
No
Human Impact
High

Priority Score

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

Attack Technique

OS command injection occurs when an application passes unsanitized user input directly into system shell commands.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

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

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-49869 CRITICAL POC
10.0 Jun 26

Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

Vendor StatusVendor

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