CVE-2026-113726
virtualenv activate runs commands from the environment name in zsh with PROMPT_SUBST
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.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.8
virtualenv activate runs commands from the environment name in zsh with PROMPT_SUBST
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.
- Record
CVE-2026-113726- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-78, CWE-116
- Updated
- 2026-11-02
EUVDEUVD-2026-106869
7.8
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.
- Record
EUVD-2026-106869- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-5vjq-rrrf-7h2q
7.8
virtualenv activate runs commands from the environment name in zsh with PROMPT_SUBST
Impact
zsh users activate an environment with the bash activate script, which puts the environment name into PS1. Since
21.13.0 the script escapes backslashes, dollar signs and backticks in that name, but only when BASH_VERSION is set, so
zsh gets the raw value. With the PROMPT_SUBST option set, zsh runs parameter expansion, command substitution and
arithmetic expansion on PS1 each time it draws the prompt. A name that contains $(...), backticks or ${...} then
runs as commands in the user's shell, once per prompt.
The name comes from the environment directory, or from --prompt or VIRTUALENV_PROMPT. After you create an
environment with:
$ virtualenv 'x$(touch PWNED)y'
source 'x$(touch PWNED)y/bin/activate' in a zsh session with PROMPT_SUBST set creates PWNED, and the prompt shows
(xy). Passing that value as --prompt to an environment with a plain name has the same effect. Without
PROMPT_SUBST, zsh shows the name as text and runs nothing. bash runs nothing either.
A plain zsh starts with PROMPT_SUBST off. oh-my-zsh users have it on: oh-my-zsh loads
lib/theme-and-appearance.zsh
at startup, and that file sets it. An attacker needs to influence the environment path or prompt: a CI job or wrapper
tool that passes a branch, project or job name through, or a directory in a cloned repository or unpacked archive.
--prompt . takes the current directory's name.
zsh also reads % in PS1 as a prompt escape, so a name with %n showed the user name in place of those characters,
though without running commands.
The bug is in releases up to and including 21.14.3. The payload runs on 20.26.6 and 21.14.3, and the reporter confirmed 21.9.1.
Patches
Fixed in 21.14.4. Under zsh, activate now escapes the name the way it does under bash and doubles
%, so the example above runs nothing and the prompt shows the name as given. zsh gets the escaping even when
PROMPT_SUBST is off, because a user can set the option after activation; a name with a backslash, dollar sign or
backtick then shows the added backslashes.
Fix: https://github.com/pypa/virtualenv/commit/5b915367da82bd024b2a0d28d2f98007034b4aa2
Workarounds
Set VIRTUAL_ENV_DISABLE_PROMPT=1 before you source activate, which leaves PS1 alone, or run
unsetopt prompt_subst if your prompt does not need it. Check the name of an environment you did not create before you
source its activate.
Credits
Kaya Emre Arikan (@kemrec) reported this issue.
- Record
GHSA-5vjq-rrrf-7h2q- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-78, CWE-116
- Updated
- 2026-11-02
NVD
7.8
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.
- Record
CVE-2026-113726- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-78, CWE-116
- Updated
- 2026-11-02
OSV
7.8
virtualenv activate runs commands from the environment name in zsh with PROMPT_SUBST
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.
- Record
CVE-2026-113726- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-116, CWE-78
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-113726
7.8
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.
- Record
DEBIAN-CVE-2026-113726- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
Show 7 moreShow less
OSVGHSA-5vjq-rrrf-7h2q
7.8
virtualenv activate runs commands from the environment name in zsh with PROMPT_SUBST
Impact
zsh users activate an environment with the bash activate script, which puts the environment name into PS1. Since
21.13.0 the script escapes backslashes, dollar signs and backticks in that name, but only when BASH_VERSION is set, so
zsh gets the raw value. With the PROMPT_SUBST option set, zsh runs parameter expansion, command substitution and
arithmetic expansion on PS1 each time it draws the prompt. A name that contains $(...), backticks or ${...} then
runs as commands in the user's shell, once per prompt.
The name comes from the environment directory, or from --prompt or VIRTUALENV_PROMPT. After you create an
environment with:
$ virtualenv 'x$(touch PWNED)y'
source 'x$(touch PWNED)y/bin/activate' in a zsh session with PROMPT_SUBST set creates PWNED, and the prompt shows
(xy). Passing that value as --prompt to an environment with a plain name has the same effect. Without
PROMPT_SUBST, zsh shows the name as text and runs nothing. bash runs nothing either.
A plain zsh starts with PROMPT_SUBST off. oh-my-zsh users have it on: oh-my-zsh loads
lib/theme-and-appearance.zsh
at startup, and that file sets it. An attacker needs to influence the environment path or prompt: a CI job or wrapper
tool that passes a branch, project or job name through, or a directory in a cloned repository or unpacked archive.
--prompt . takes the current directory's name.
zsh also reads % in PS1 as a prompt escape, so a name with %n showed the user name in place of those characters,
though without running commands.
The bug is in releases up to and including 21.14.3. The payload runs on 20.26.6 and 21.14.3, and the reporter confirmed 21.9.1.
Patches
Fixed in 21.14.4. Under zsh, activate now escapes the name the way it does under bash and doubles
%, so the example above runs nothing and the prompt shows the name as given. zsh gets the escaping even when
PROMPT_SUBST is off, because a user can set the option after activation; a name with a backslash, dollar sign or
backtick then shows the added backslashes.
Fix: https://github.com/pypa/virtualenv/commit/5b915367da82bd024b2a0d28d2f98007034b4aa2
Workarounds
Set VIRTUAL_ENV_DISABLE_PROMPT=1 before you source activate, which leaves PS1 alone, or run
unsetopt prompt_subst if your prompt does not need it. Check the name of an environment you did not create before you
source its activate.
Credits
Kaya Emre Arikan (@kemrec) reported this issue.
- Record
GHSA-5vjq-rrrf-7h2q- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Weakness
- CWE-116, CWE-78
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-113726
7.8
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.
- Record
UBUNTU-CVE-2026-113726- CVSS 3.1
- 7.8 High
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
OSVAZL-110076 No score
CVE-2026-113726 affecting package python-pip 24.2-10
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.
- Record
AZL-110076- Updated
- 2026-11-02
OSVAZL-110100 No score
CVE-2026-113726 affecting package python-virtualenv for versions less than 20.36.1-10
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.
- Record
AZL-110100- Updated
- 2026-11-07
OSVBIT-virtualenv-2026-113726 No score
virtualenv activate runs commands from the environment name in zsh with PROMPT_SUBST
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.
- Record
BIT-virtualenv-2026-113726- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:12372-1 No score
python313-virtualenv-21.15.1-1.1 on GA media
These are all security issues fixed in the python313-virtualenv-21.15.1-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12372-1- Updated
- 2026-11-02
OSVROOT-APP-PYPI-CVE-2026-113726 No score
CVE-2026-113726 in virtualenv - Patched by Root
Root has patched CVE-2026-113726 in the virtualenv package for Root:PyPI. Multiple fixed versions available.
- Record
ROOT-APP-PYPI-CVE-2026-113726- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
virtualenvPyPI |
through 21.14.3 | 21.14.4 |
python-pipAzure Linux:3 |
through 24.2-10 | None known |
python-virtualenvAzure Linux:3 |
before 20.36.1-10 | 20.36.1-10 |
virtualenvBitnami |
before 21.14.4 | 21.14.4 |
python-virtualenvDebian:12 |
All versions, plus listed versions 20.17.1+ds-120.19.0+ds-120.21.0+ds-120.23.0+ds-120.23.0+ds-2 Show 28 moreShow less20.24.1+ds-120.24.6+ds-120.24.6+ds-220.25.0+ds-120.25.0+ds-220.25.1+ds-120.26.1+ds-120.26.2+ds-120.26.6+ds-120.27.0+ds-120.28.0+ds-120.29.1+ds-120.29.3+ds-120.30.0+ds-120.30.0+ds-220.30.0+ds-320.31.2+ds-120.33.1+ds-120.34.0+ds-120.35.3+ds-120.35.4+ds-120.36.1+ds-120.38.0+ds-121.2.0+ds-121.2.4+ds-121.3.1+ds-121.4.1+ds-121.5.1+ds-1 |
None known |
python-virtualenvDebian:13 |
All versions, plus listed versions 20.31.2+ds-120.31.2+ds-1+deb13u120.33.1+ds-120.34.0+ds-120.35.3+ds-1 Show 8 moreShow less20.35.4+ds-120.36.1+ds-120.38.0+ds-121.2.0+ds-121.2.4+ds-121.3.1+ds-121.4.1+ds-121.5.1+ds-1 |
None known |
python-virtualenvDebian:14 |
All versions, plus listed versions 20.31.2+ds-120.33.1+ds-120.34.0+ds-120.35.3+ds-120.35.4+ds-1 Show 7 moreShow less20.36.1+ds-120.38.0+ds-121.2.0+ds-121.2.4+ds-121.3.1+ds-121.4.1+ds-121.5.1+ds-1 |
None known |
virtualenvPyPI |
before 21.14.4, plus listed versions 0.80.8.10.8.20.8.30.8.4 Show 45 moreShow less0.90.9.10.9.21.01.11.101.10.11.111.11.11.11.21.11.31.11.41.11.51.11.61.21.31.3.11.3.21.3.31.3.41.41.4.11.4.21.4.31.4.41.4.51.4.61.4.71.4.81.4.91.4rc11.51.5.11.5.21.61.6.11.6.21.6.31.6.41.71.7.11.7.1.11.7.1.21.7.21.8 |
21.14.4 |
virtualenvRoot:PyPI |
before 20.26.6+aikido.5 | 20.26.6+aikido.521.3.2+aikido.321.7.1+aikido.321.13.0+aikido.121.7.5+aikido.421.14.1+aikido.121.7.8+aikido.321.9.0+aikido.221.7.13+aikido.221.11.1+aikido.221.7.10+aikido.521.7.4+aikido.621.14.2+aikido.221.6.1+aikido.321.4.2+aikido.221.9.0+aikido.321.7.5+aikido.521.7.1+aikido.421.12.1+aikido.321.7.9+aikido.421.4.3+aikido.321.2.4+aikido.421.7.16+aikido.221.3.2+aikido.4 |
python-virtualenvUbuntu:14.04:LTS |
All versions, plus listed versions 1.10.1-11.11-11.11-21.11.4-11.11.4-1ubuntu1 |
None known |
Show 8 moreShow less
| Package | Affected | Fixed |
|---|---|---|
python-virtualenvUbuntu:16.04:LTS |
All versions, plus listed versions 1.11.6+ds-114.0.5+ds-114.0.5+ds-214.0.5+ds-415.0.0+ds-1 Show 6 moreShow less15.0.0+ds-215.0.1+ds-115.0.1+ds-215.0.1+ds-315.0.1+ds-3ubuntu115.0.1+ds-3ubuntu1.1 |
None known |
python-virtualenvUbuntu:18.04:LTS |
All versions, plus listed versions 15.1.0+ds-115.1.0+ds-1.1 |
None known |
python-virtualenvUbuntu:Pro:20.04:LTS |
All versions, plus listed versions 15.1.0+ds-215.1.0+ds-2build115.1.0+ds-2ubuntu120.0.13-120.0.17-120.0.17-1ubuntu0.320.0.17-1ubuntu0.420.0.17-1ubuntu0.4+esm1 |
None known |
python-virtualenvUbuntu:Pro:22.04:LTS |
All versions, plus listed versions 20.4.6+ds-220.10.0+ds-120.12.1+ds-120.13.0+ds-120.13.0+ds-220.13.0+ds-2ubuntu0.1~esm1 |
None known |
python-virtualenvUbuntu:Pro:24.04:LTS |
All versions, plus listed versions 20.24.1+ds-120.24.6+ds-120.24.6+ds-220.25.0+ds-120.25.0+ds-220.25.0+ds-2ubuntu0.1~esm1 |
None known |
python-virtualenvUbuntu:26.10 |
All versions, plus listed versions 20.36.1+ds-121.4.1+ds-121.5.1+ds-1 |
None known |
python-virtualenvUbuntu:26.04:LTS |
All versions, plus listed versions 20.31.2+ds-120.35.3+ds-120.35.4+ds-120.36.1+ds-1 |
None known |
python-virtualenvopenSUSE:Tumbleweed From an advisory covering 9 CVEs |
before 21.15.1-1.1 | 21.15.1-1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | OSV | |
| affected | ||
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-113726 is a high vulnerability (CVSS 7.8) in Pypa Virtualenv, published October 20, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.34%, the 28th percentile. Fixed in virtualenv 21.14.4.
References
github.com/pypa/virtualenv/security/advisories/GHSA-5vjq-rrrf-7h2q
github.com/pypa/virtualenv/commit/5b915367da82bd024b2a0d28d2f98007034b4aa2
github.com/pypa/virtualenv/releases/tag/21.14.4
nvd.nist.gov/vuln/detail/CVE-2026-113726
github.com/advisories/GHSA-5vjq-rrrf-7h2q
github.com/CVEProject/cvelistV5/tree/main/cves/2026/113xxx/CVE-2026-113726.json
Show 13 moreShow less
security-tracker.debian.org/tracker/CVE-2026-113726
github.com/pypa/virtualenv
ubuntu.com/security/CVE-2026-113726
cve.org/CVERecord?id=CVE-2026-113726
suse.com/security/cve/CVE-2026-113714
suse.com/security/cve/CVE-2026-113716
suse.com/security/cve/CVE-2026-113718
suse.com/security/cve/CVE-2026-113720
suse.com/security/cve/CVE-2026-113722
suse.com/security/cve/CVE-2026-113724
suse.com/security/cve/CVE-2026-113726
suse.com/security/cve/CVE-2026-113732
suse.com/security/cve/CVE-2026-115586
Left out here: 249 versions. The JSON record has them.