CVE-2026-113732
virtualenv activate.fish runs commands from a path or prompt with a backslash before a quote
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.
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.fish runs commands from a path or prompt with a backslash before a quote
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.
- Record
CVE-2026-113732- 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-106866
7.8
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.
- Record
EUVD-2026-106866- 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-c947-3pg5-gm8q
7.8
virtualenv activate.fish runs commands from a path or prompt with a backslash before a quote
Impact
FishActivator defines no quote(), so it inherits ViaTemplateActivator.quote, which returns shlex.quote(string). That function follows POSIX sh rules, where a backslash inside single quotes stays a literal character. fish reads \' inside single quotes as an escaped quote and \\ as an escaped backslash. A value with a backslash before a quote therefore ends the literal somewhere other than where shlex.quote put the end, and fish expands the command substitution that follows.
The environment path reaches set -gx VIRTUAL_ENV, and --prompt or VIRTUALENV_PROMPT reaches set -gx VIRTUAL_ENV_PROMPT. For --prompt "x\'\$(touch PWNED)'\'", the generated activate.fish contains:
set -gx VIRTUAL_ENV_PROMPT 'x\'"'"'$(touch PWNED)'"'"'\'"'"''
source bin/activate.fish runs touch PWNED, and fish prints no error. The same payload as a directory name runs through VIRTUAL_ENV. --prompt . takes the current directory's name, so running virtualenv inside a directory someone else named is enough. Without the backslash the payload runs nothing, and under bash it runs nothing either.
virtualenv generates activate.fish by default. 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.
The bug affects every release up to 21.14.1 that ships activate.fish. The GHSA-p58f-9548-mpm2 fix in 21.7.13 moved the placeholders outside their quotes but kept shlex.quote.
Patches
Fixed in 21.14.2. activate.fish now escapes backslashes and single quotes the way fish reads them, so the example above runs nothing and shows the prompt as given. Fix: https://github.com/pypa/virtualenv/commit/3bddeaf8d02c3ee7f576503efb082f8f494cfcab
Workarounds
Do not create an environment whose path or prompt contains a backslash, and inspect activate.fish before you source one you did not create.
Credits
Kevin Stubbings (@Kwstubbs) of GitHub Security Lab reported this issue.
- Record
GHSA-c947-3pg5-gm8q- 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.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.
- Record
CVE-2026-113732- 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.fish runs commands from a path or prompt with a backslash before a quote
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.
- Record
CVE-2026-113732- 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-113732
7.8
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.
- Record
DEBIAN-CVE-2026-113732- 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 6 moreShow less
OSVGHSA-c947-3pg5-gm8q
7.8
virtualenv activate.fish runs commands from a path or prompt with a backslash before a quote
Impact
FishActivator defines no quote(), so it inherits ViaTemplateActivator.quote, which returns shlex.quote(string). That function follows POSIX sh rules, where a backslash inside single quotes stays a literal character. fish reads \' inside single quotes as an escaped quote and \\ as an escaped backslash. A value with a backslash before a quote therefore ends the literal somewhere other than where shlex.quote put the end, and fish expands the command substitution that follows.
The environment path reaches set -gx VIRTUAL_ENV, and --prompt or VIRTUALENV_PROMPT reaches set -gx VIRTUAL_ENV_PROMPT. For --prompt "x\'\$(touch PWNED)'\'", the generated activate.fish contains:
set -gx VIRTUAL_ENV_PROMPT 'x\'"'"'$(touch PWNED)'"'"'\'"'"''
source bin/activate.fish runs touch PWNED, and fish prints no error. The same payload as a directory name runs through VIRTUAL_ENV. --prompt . takes the current directory's name, so running virtualenv inside a directory someone else named is enough. Without the backslash the payload runs nothing, and under bash it runs nothing either.
virtualenv generates activate.fish by default. 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.
The bug affects every release up to 21.14.1 that ships activate.fish. The GHSA-p58f-9548-mpm2 fix in 21.7.13 moved the placeholders outside their quotes but kept shlex.quote.
Patches
Fixed in 21.14.2. activate.fish now escapes backslashes and single quotes the way fish reads them, so the example above runs nothing and shows the prompt as given. Fix: https://github.com/pypa/virtualenv/commit/3bddeaf8d02c3ee7f576503efb082f8f494cfcab
Workarounds
Do not create an environment whose path or prompt contains a backslash, and inspect activate.fish before you source one you did not create.
Credits
Kevin Stubbings (@Kwstubbs) of GitHub Security Lab reported this issue.
- Record
GHSA-c947-3pg5-gm8q- 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-113732
7.8
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.
- Record
UBUNTU-CVE-2026-113732- 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-110091 No score
CVE-2026-113732 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.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.
- Record
AZL-110091- Updated
- 2026-11-07
OSVBIT-virtualenv-2026-113732 No score
virtualenv activate.fish runs commands from a path or prompt with a backslash before a quote
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.
- Record
BIT-virtualenv-2026-113732- 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-113732 No score
CVE-2026-113732 in virtualenv - Patched by Root
Root has patched CVE-2026-113732 in the virtualenv package for Root:PyPI. Multiple fixed versions available.
- Record
ROOT-APP-PYPI-CVE-2026-113732- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
virtualenvPyPI |
through 21.14.1 | 21.14.2 |
python-virtualenvAzure Linux:3 |
before 20.36.1-10 | 20.36.1-10 |
virtualenvBitnami |
before 21.14.2 | 21.14.2 |
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.2, 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.2 |
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.13+aikido.121.7.16+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.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 |
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 |
Show 7 moreShow less
| Package | Affected | Fixed |
|---|---|---|
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-113732 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.24%, the 14th percentile. Fixed in virtualenv 21.14.2.
References
github.com/pypa/virtualenv/security/advisories/GHSA-c947-3pg5-gm8q
github.com/pypa/virtualenv/commit/3bddeaf8d02c3ee7f576503efb082f8f494cfcab
github.com/pypa/virtualenv/releases/tag/21.14.2
nvd.nist.gov/vuln/detail/CVE-2026-113732
github.com/advisories/GHSA-c947-3pg5-gm8q
github.com/CVEProject/cvelistV5/tree/main/cves/2026/113xxx/CVE-2026-113732.json
Show 13 moreShow less
security-tracker.debian.org/tracker/CVE-2026-113732
github.com/pypa/virtualenv
ubuntu.com/security/CVE-2026-113732
cve.org/CVERecord?id=CVE-2026-113732
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: 247 versions. The JSON record has them.