Source: python-virtualenv Version: 21.5.1+ds-1 X-Debbugs-CC: [email protected] Severity: important Tags: security upstream
Hi, The following vulnerabilities were published for python-virtualenv. CVE-2026-113713[0]: | virtualenv is a tool for creating isolated virtual python | environments. From 21.14.8 until 21.14.10, the app-data seeder can | leave an environment linked to temporary package files that | virtualenv deletes when creation finishes. The environment-variable | and configuration-file forms of symlink_app_data can enable this | state even though the command-line flag is disabled for temporary | app-data. The resulting environment depends on a cache pathname that | its owner no longer controls. This issue is fixed in version | 21.14.10. CVE-2026-113714[1]: | virtualenv is a tool for creating isolated virtual python | environments. 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. | The wrong path can then be hashed, while a digest mismatch leaves | the rejected archive in the cache for later selection without | verification. A separate rejected-cache-file variant requires | control over downloaded data or archive selection but not the | forged-line prerequisites. Explicit custom-index exceptions are | outside the promised PyPI comparison, and the issue does not | independently bypass TLS or establish control of default PyPI. This | issue is fixed in version 21.14.9. CVE-2026-113715[2]: | virtualenv is a tool for creating isolated virtual python | environments. Prior to 21.14.9, the stdlib venv creator reads | 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, causing path data to change configuration | structure before final output. Setting include-system-site-packages | to true weakens environment isolation, while an altered home can | change which standard-library files the interpreter loads if the | attacker also controls that location. The builtin creator does not | use this readback path. This issue is fixed in version 21.14.9. CVE-2026-113716[3]: | virtualenv is a tool for creating isolated virtual python | environments. Prior to 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 when another local account prepared the | tree and the invoking user can access the target. The --clear option | removes the planted tree first, while ordinary creation reaches it; | arbitrary attacker-selected output bytes are not established. This | issue is fixed in version 21.14.9. CVE-2026-113717[4]: | virtualenv is a tool for creating isolated virtual python | environments. Prior to 21.14.9, PipInvoke.get_pip_install_cmd() | handles --seeder pip --download by calling get_wheel(download=False) | and then allowing pip to consult the configured index, bypassing | virtualenv's download_wheel() and verify_wheel_digest() path. When | virtualenv's default-index PyPI digest comparison remains enabled, | an index candidate matching the bundled package and version can | therefore be selected without comparison to PyPI SHA-256 metadata. | Explicit custom-index settings already opt out of that comparison | and remain outside this verification-bypass claim; the demonstrated | configuration used a non-PyPI index while leaving the index | environment variables unset so the comparison policy remained | active. This condition does not independently defeat TLS or | establish control of the index response. This issue is fixed in | version 21.14.9. CVE-2026-113718[5]: | virtualenv is a tool for creating isolated virtual python | environments. Prior to 21.14.9, POSIX xonsh activation quote() uses | repr() to write printable non-ASCII prompt or destination data into | UTF-8 activate.xsh, while xonsh can read that script using | $XONSH_ENCODING. Under a legacy multibyte codec such as GBK or Big5, | a UTF-8 trail byte can consume the backslash before an adjacent | quote, allowing the literal to close and attacker-influenced | statements to execute when the user sources the generated script. | This issue is fixed in version 21.14.9. CVE-2026-113719[6]: | 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. CVE-2026-113720[7]: | virtualenv is a tool for creating isolated virtual python | environments. Prior to 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 therefore produce files | writable by another local account in a later traversable | environment, allowing package code such as pip/__init__.py to be | modified and executed by the environment owner. The attacker cannot | force the earlier umask, and a private destination parent prevents | access. This issue is fixed in version 21.14.9. CVE-2026-113721[8]: | virtualenv is a tool for creating isolated virtual python | environments. Prior to 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 | that prepares final entries inside the destination can therefore | cause environment creation to create or overwrite files outside the | requested tree with constrained virtualenv-generated content and the | invoking user's permissions. The destination parent must remain | controlled by the environment owner during creation; concurrent | parent-directory replacement is a separate concern. This issue is | fixed in version 21.14.9. CVE-2026-113722[9]: | virtualenv is a tool for creating isolated virtual python | environments. Prior to 21.14.9, virtualenv's ScriptMakerCustom and | pip pass an incompletely quoted interpreter path to distlib | ScriptMaker 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. An attacker who | influences the environment destination can therefore execute | commands with the user's privileges when the user later runs a | generated launcher; environment creation and activation do not | trigger the command. Existing launchers are not repaired by | upgrading virtualenv alone and must be regenerated, while a later | independent pip installation or upgrade can reintroduce an affected | launcher because pip's vendored distlib is unchanged. The virtualenv | fix is released in version 21.14.9. CVE-2026-113723[10]: | 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. This | vulnerability is fixed in 21.14.9. CVE-2026-113724[11]: | virtualenv is a tool for creating isolated virtual python | environments. Prior to 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 therefore cause a victim-owned target | outside the destination that is initially not writable by the | invoking user to become broadly writable before the retry fails, | provided that user owns the target and can change its mode. Another | account can use the widened mode only if it can traverse the | target's parent directories; root does not reach the demonstrated | failure path, and the operation does not itself read the target. | This issue is fixed in version 21.14.9. CVE-2026-113725[12]: | 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. This issue is fixed in version 21.14.7. CVE-2026-113726[13]: | virtualenv is a tool for creating isolated virtual python | environments. 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. The | script assigns that value to PS1. In zsh with PROMPT_SUBST, an | attacker-influenced environment directory, --prompt, or | VIRTUALENV_PROMPT value containing command, parameter, or arithmetic | expansion syntax can therefore execute commands in the user's shell | each time the prompt is drawn. A percent sign is separately | interpreted as a zsh prompt escape but does not by itself execute | commands. Plain zsh with PROMPT_SUBST disabled and bash are not | affected by this mechanism. This issue is fixed in version 21.14.4. CVE-2026-113732[14]: | virtualenv is a tool for creating isolated virtual python | environments. 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 environment path, --prompt, or VIRTUALENV_PROMPT | value containing a backslash before a quote can therefore terminate | the generated fish literal and execute command substitution when the | user sources activate.fish. This issue is fixed in version 21.14.2. CVE-2026-113776[15]: | 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. If you fix the vulnerabilities please also make sure to include the CVE (Common Vulnerabilities & Exposures) ids in your changelog entry. For further information see: [0] https://security-tracker.debian.org/tracker/CVE-2026-113713 https://www.cve.org/CVERecord?id=CVE-2026-113713 [1] https://security-tracker.debian.org/tracker/CVE-2026-113714 https://www.cve.org/CVERecord?id=CVE-2026-113714 [2] https://security-tracker.debian.org/tracker/CVE-2026-113715 https://www.cve.org/CVERecord?id=CVE-2026-113715 [3] https://security-tracker.debian.org/tracker/CVE-2026-113716 https://www.cve.org/CVERecord?id=CVE-2026-113716 [4] https://security-tracker.debian.org/tracker/CVE-2026-113717 https://www.cve.org/CVERecord?id=CVE-2026-113717 [5] https://security-tracker.debian.org/tracker/CVE-2026-113718 https://www.cve.org/CVERecord?id=CVE-2026-113718 [6] https://security-tracker.debian.org/tracker/CVE-2026-113719 https://www.cve.org/CVERecord?id=CVE-2026-113719 [7] https://security-tracker.debian.org/tracker/CVE-2026-113720 https://www.cve.org/CVERecord?id=CVE-2026-113720 [8] https://security-tracker.debian.org/tracker/CVE-2026-113721 https://www.cve.org/CVERecord?id=CVE-2026-113721 [9] https://security-tracker.debian.org/tracker/CVE-2026-113722 https://www.cve.org/CVERecord?id=CVE-2026-113722 [10] https://security-tracker.debian.org/tracker/CVE-2026-113723 https://www.cve.org/CVERecord?id=CVE-2026-113723 [11] https://security-tracker.debian.org/tracker/CVE-2026-113724 https://www.cve.org/CVERecord?id=CVE-2026-113724 [12] https://security-tracker.debian.org/tracker/CVE-2026-113725 https://www.cve.org/CVERecord?id=CVE-2026-113725 [13] https://security-tracker.debian.org/tracker/CVE-2026-113726 https://www.cve.org/CVERecord?id=CVE-2026-113726 [14] https://security-tracker.debian.org/tracker/CVE-2026-113732 https://www.cve.org/CVERecord?id=CVE-2026-113732 [15] https://security-tracker.debian.org/tracker/CVE-2026-113776 https://www.cve.org/CVERecord?id=CVE-2026-113776 Regards, Salvatore

