virtualenv vulnerabilities
21 known CVE vulnerabilities in virtualenv, translated and rated.
- CVE-2026-115586High
In virtualenv from 21.14.9 until 21.14.13, the bash bin/activate script can copy an attacker-controlled --prompt value into PS1 without escaping dollar signs or backticks when both promptvars and POSIX mode are disabled during activation. Re-enabling promptvars, running set -o posix, or starting an interactive child bash that inherits the exported PS1 can then expand command substitution in the stored VIRTUAL_ENV_PROMPT value and execute commands as the user who activates the environment. This issue is fixed in version 21.14.13.
- CVE-2026-113776High
In virtualenv from 20.26.6 until 21.14.2, ViaTemplateActivator.instantiate_template() replaces placeholders one key at a time across the activation template, allowing trigger names such as __VIRTUAL_NAME__ inside an already substituted path to be replaced again. This can lead to command execution when activating the environment via bash, fish, xonsh, or activate_this.py if an attacker influences the destination path or --prompt.
- CVE-2026-113732High
In virtualenv prior to 21.14.2, FishActivator inherits ViaTemplateActivator.quote(), which uses POSIX shlex.quote() even though fish interprets backslashes and single quotes differently. An attacker-influenced path, --prompt, or VIRTUALENV_PROMPT value containing a backslash before a quote can terminate the fish literal and execute command substitution when the user sources activate.fish.
- CVE-2026-113726High
In virtualenv prior to 21.13.0, the bash activate script that zsh also sources leaves the environment name unescaped; from 21.13.0 until 21.14.4, it escapes backslashes, dollar signs, and backticks only when BASH_VERSION is set, so zsh receives the raw value assigned to PS1. In zsh with PROMPT_SUBST, an attacker-influenced value containing expansion syntax can execute commands each time the prompt is drawn.
- CVE-2026-113725High
virtualenv is a tool for creating isolated virtual Python environments. Prior to 21.14.7, the bash activate script escapes the environment name for only one of the two passes bash makes over PS1, so a backslash in the name undoes the escaping and a name containing \$(...) runs as commands in the user's shell each time bash draws the prompt.
- CVE-2026-113724Medium
In virtualenv before 21.14.9, the safe_delete() deletion error handler responds to a failed removal by reading mode bits with os.lstat(path) and applying owner-write permission with os.chmod(path, ...), which follows a symlink. A planted link inside a read-only directory can cause a victim-owned target outside the destination to become broadly writable.
- CVE-2026-113723High
virtualenv is a tool for creating isolated virtual Python environments. Prior to 21.14.9, caller-supplied prompt text can become executable syntax in the bash activation prompt. An attacker must influence the value passed to virtualenv, and a user must subsequently activate the environment and draw the prompt.
- CVE-2026-113722High
Prior to 21.14.9, virtualenv incompletely quotes the interpreter path when generating POSIX console scripts. When the path contains a space or produces a shebang longer than 127 bytes, distlib emits a /bin/sh wrapper whose double-quoted interpreter path still expands command substitutions and backticks, allowing command execution with the user's privileges when the generated launcher is later run.
- CVE-2026-113721Medium
In virtualenv before 21.14.9, ViaTemplateActivator._generate() removes an existing output only when Path.exists() is true, allowing a dangling symlink to survive and redirect generated activation content, while PyEnvCfg.write() opens pyvenv.cfg without first replacing an existing symbolic or hard link. Another local account can cause files outside the requested tree to be created or overwritten.
- CVE-2026-113720Medium
In virtualenv before 21.14.9, the app-data copy seeder uses shutil.copy() to copy cached package files into later environments, causing cached source modes to override the current run's umask. A cache populated under a permissive umask can produce files writable by another local account in a later traversable environment.
- CVE-2026-113719Medium
In virtualenv before 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 files outside the environment to be deleted.
- CVE-2026-113718High
Prior to 21.14.9, virtualenv's POSIX xonsh activation uses repr() to write printable non-ASCII data into a UTF-8 activate.xsh, which xonsh may read under a legacy multibyte codec such as GBK or Big5. A UTF-8 trail byte can then consume the backslash before an adjacent quote, allowing the literal to close and attacker-influenced statements to execute when the script is sourced.
- CVE-2026-113717Low
In virtualenv prior to 21.14.9, PipInvoke.get_pip_install_cmd() handles --seeder pip --download by calling get_wheel(download=False) and allowing pip to consult the configured index, bypassing virtualenv's download_wheel() and verify_wheel_digest() path. When default-index PyPI digest comparison is enabled, an index candidate matching the bundled package and version can be selected without comparison to PyPI SHA-256 metadata.
- CVE-2026-113716Medium
In virtualenv before 21.14.9, the builtin creator calls ensure_dir() for executable, library, and package directories, and ensure_dir() accepts an existing symlink to a directory because exists() follows it. Interpreter creation, seed installation, and activation generation then write through the linked parent outside the requested destination.
- CVE-2026-113715Low
In virtualenv prior to 21.14.9, the stdlib venv creator reads the generated pyvenv.cfg with str.splitlines() and merges parsed keys over virtualenv's selected configuration. An untrusted caller who influences the destination pathname can include a line-boundary character such as U+2028 to inject keys including home and include-system-site-packages, altering the configuration structure.
- CVE-2026-113714Low
In virtualenv prior to 21.14.9, download_wheel() writes package-index downloads directly into the reusable wheel/house cache before selecting a verification target from pip's textual Saved output. With default-index digest comparison enabled, a controlled package index can inject a misleading Saved line through a discarded link's data-requires-python attribute; this forged-line variant also requires knowledge of an absolute path to the genuine bundled wheel.
- CVE-2026-113713Medium
In virtualenv versions 21.14.8 through 21.14.10, the app-data seeder can leave an environment linked to temporary package files that virtualenv deletes when creation finishes. Enabling symlink_app_data via environment variable or configuration file can trigger this state even though the command-line flag is disabled for temporary app-data. The resulting environment depends on a cache pathname its owner no longer controls. This is fixed in version 21.14.10.
- CVE-2026-102938Medium
virtualenv is a tool for creating isolated virtual Python environments. Prior to 21.7.11, PyEnvCfg.write() writes prompt values verbatim to the line-oriented pyvenv.cfg format while PyEnvCfg._read_values() parses the file with str.splitlines() and accepts the last value for duplicate keys. An attacker who influences --prompt, VIRTUALENV_PROMPT, or configuration input can insert a recognized line boundary and additional keys, including home, causing consumers to use an attacker-selected base interpreter or corrupted environment metadata.
- CVE-2026-102937High
In virtualenv prior to 21.7.12, BatchActivator.quote() returns prompt text unchanged before activate.bat inserts it into a cmd.exe set "VAR=value" statement. An attacker who influences --prompt, VIRTUALENV_PROMPT, or the corresponding configuration value can include a double quote that closes the assignment and leaves following cmd.exe operators as executable syntax. When a user activates the generated Windows environment, the injected commands run with that user's privileges.
- CVE-2026-102930High
In virtualenv 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.
- CVE-2026-102925High
In virtualenv prior to 21.7.13, the generated activate (bash and zsh) and activate.fish scripts place values already escaped by shlex.quote inside an additional quoted context. In the bash and zsh script, a crafted virtual environment path reaches __VIRTUAL_ENV__ when a relocated environment's recorded directory is absent; in the fish script, crafted Tcl or Tk library paths reach __TCL_LIBRARY__ or __TK_LIBRARY__. The surplus quotes can terminate the data-only quoted run and leave shell metacharacters parsed as commands when a user sources the activation script, allowing code execution with that user's privileges.
Vulnerability data from NVD (NIST) · CISA KEV · EPSS

