Every CVE Search/ Get API key

CVE-2026-113722

virtualenv: Generated POSIX console launchers interpret destination paths as shell syntax

7.8 HighFix available

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.

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

0.29%Up 0.1 points since Oct 21, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.8

virtualenv: Generated POSIX console launchers interpret destination paths as shell syntax

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.

Record
CVE-2026-113722
CVSS 3.1
7.8 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
EUVDEUVD-2026-105304 7.8

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.

Record
EUVD-2026-105304
CVSS 3.1
7.8 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-c978-59m8-c77v 7.8

virtualenv: Generated POSIX console launchers interpret destination paths as shell syntax

Summary

A destination path supplied to virtualenv can be interpreted as shell syntax by a generated POSIX console launcher. The app-data seeder and pip delegate launcher generation to distlib but supply the interpreter path in a form that does not preserve it as literal data in the shell wrapper.

Affected area

POSIX console scripts generated by the app-data seeder or pip when the interpreter path requires a shell wrapper. Windows executable launchers are not affected by this path.

Attacker-controlled input

An attacker must influence the environment destination passed to virtualenv, and the user must subsequently run a generated launcher. The attacker does not need to modify an installed executable or control the user's app-data cache.

Affected code

The relevant 21.14.8 source is in ScriptMakerCustom.

Mechanism

The app-data seeder passes the environment's interpreter path through enquote_executable() to distlib's ScriptMaker. It adds double quotes for a path with a space but does not escape shell expansions inside those quotes. When the path has a space or the shebang exceeds 127 bytes, distlib emits a #!/bin/sh wrapper with a line shaped like '''exec' "<path>" "$0" "$@". The shell expands $(...) and backticks in that path when the launcher is run. The same wrapper must also parse as Python, which exposes additional quote and backslash cases. Environment creation and activation do not trigger the shell payload.

Reproduction and evidence

The scanner created three environments: a control under my -touch PWNED- project, one under my $(touch PWNED) project, and one under a path of more than 127 bytes ending in $(touch${IFS}PWNED). Each was created without producing PWNED. Running the generated bin/pip --version created PWNED in both attack cases; the control created none. The long-path case reached the shell wrapper without a space. This reproduces execution by the generated launcher, with the user's privileges, rather than during seeding.

The report dates the app-data seeder's distlib launcher integration to #1579, first released in 20.0.2. PR #3417 quotes the raw interpreter path for the POSIX wrapper and repairs launchers written by the pip seeder. Pip's own distlib can write a vulnerable wrapper again during a later pip install or upgrade; the proposed virtualenv fix does not change pip's vendored code. The maintainer-provided follow-up review reports that later path separately.

Attack sequence

sequenceDiagram
    participant A as Destination supplier
    participant V as virtualenv seeder
    participant D as distlib ScriptMaker
    participant S as Generated bin/pip
    participant U as User
    A->>V: path contains $(touch PWNED)
    V->>D: pass interpreter path with incomplete shell quoting
    D->>S: write /bin/sh wrapper
    Note over V,S: no payload runs during creation or activation
    U->>S: pip --version
    S->>S: shell expands path and runs touch
    S-->>U: PWNED appears with user's privileges

Reproducer files

The following files are from the scanner report for ANT-2026-5DZVLGL1. They were tested against commit a857a7823c73 in the scanner image. The repro entrypoint expects companion files under /tmp/repro.d; cases that change user IDs need a disposable root-capable container. The last output line is BUG when the reported behavior occurs. These files are included as evidence and were not rerun for this advisory update.

repro

#!/usr/bin/env python3
import shutil
import subprocess
from pathlib import Path

WORK = Path("/tmp/repro-console-script")

# The attacker's whole input: the name of a directory above the environment (a repository, a project folder).
DIRECTORY_NAMES = {
    "CONTROL": "my -touch PWNED- project",
   …
Record
GHSA-c978-59m8-c77v
CVSS 3.1
7.8 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
NVD 7.8

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.

Record
CVE-2026-113722
CVSS 3.1
7.8 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
OSV 7.8

virtualenv: Generated POSIX console launchers interpret destination paths as shell syntax

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.

Record
CVE-2026-113722
CVSS 3.1
7.8 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
OSVDEBIAN-CVE-2026-113722 7.8

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.

Record
DEBIAN-CVE-2026-113722
CVSS 3.1
7.8 HighCVSS: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-c978-59m8-c77v 7.8

virtualenv: Generated POSIX console launchers interpret destination paths as shell syntax

Summary

A destination path supplied to virtualenv can be interpreted as shell syntax by a generated POSIX console launcher. The app-data seeder and pip delegate launcher generation to distlib but supply the interpreter path in a form that does not preserve it as literal data in the shell wrapper.

Affected area

POSIX console scripts generated by the app-data seeder or pip when the interpreter path requires a shell wrapper. Windows executable launchers are not affected by this path.

Attacker-controlled input

An attacker must influence the environment destination passed to virtualenv, and the user must subsequently run a generated launcher. The attacker does not need to modify an installed executable or control the user's app-data cache.

Affected code

The relevant 21.14.8 source is in ScriptMakerCustom.

Mechanism

The app-data seeder passes the environment's interpreter path through enquote_executable() to distlib's ScriptMaker. It adds double quotes for a path with a space but does not escape shell expansions inside those quotes. When the path has a space or the shebang exceeds 127 bytes, distlib emits a #!/bin/sh wrapper with a line shaped like '''exec' "<path>" "$0" "$@". The shell expands $(...) and backticks in that path when the launcher is run. The same wrapper must also parse as Python, which exposes additional quote and backslash cases. Environment creation and activation do not trigger the shell payload.

Reproduction and evidence

The scanner created three environments: a control under my -touch PWNED- project, one under my $(touch PWNED) project, and one under a path of more than 127 bytes ending in $(touch${IFS}PWNED). Each was created without producing PWNED. Running the generated bin/pip --version created PWNED in both attack cases; the control created none. The long-path case reached the shell wrapper without a space. This reproduces execution by the generated launcher, with the user's privileges, rather than during seeding.

The report dates the app-data seeder's distlib launcher integration to #1579, first released in 20.0.2. PR #3417 quotes the raw interpreter path for the POSIX wrapper and repairs launchers written by the pip seeder. Pip's own distlib can write a vulnerable wrapper again during a later pip install or upgrade; the proposed virtualenv fix does not change pip's vendored code. The maintainer-provided follow-up review reports that later path separately.

Attack sequence

sequenceDiagram
    participant A as Destination supplier
    participant V as virtualenv seeder
    participant D as distlib ScriptMaker
    participant S as Generated bin/pip
    participant U as User
    A->>V: path contains $(touch PWNED)
    V->>D: pass interpreter path with incomplete shell quoting
    D->>S: write /bin/sh wrapper
    Note over V,S: no payload runs during creation or activation
    U->>S: pip --version
    S->>S: shell expands path and runs touch
    S-->>U: PWNED appears with user's privileges

Reproducer files

The following files are from the scanner report for ANT-2026-5DZVLGL1. They were tested against commit a857a7823c73 in the scanner image. The repro entrypoint expects companion files under /tmp/repro.d; cases that change user IDs need a disposable root-capable container. The last output line is BUG when the reported behavior occurs. These files are included as evidence and were not rerun for this advisory update.

repro

#!/usr/bin/env python3
import shutil
import subprocess
from pathlib import Path

WORK = Path("/tmp/repro-console-script")

# The attacker's whole input: the name of a directory above the environment (a repository, a project folder).
DIRECTORY_NAMES = {
    "CONTROL": "my -touch PWNED- project",
   …
Record
GHSA-c978-59m8-c77v
CVSS 3.1
7.8 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
OSVUBUNTU-CVE-2026-113722 7.8

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.

Record
UBUNTU-CVE-2026-113722
CVSS 3.1
7.8 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Updated
2026-11-02
OSVAZL-110112 No score

CVE-2026-113722 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.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.

Record
AZL-110112
Updated
2026-11-07
OSVBIT-virtualenv-2026-113722 No score

virtualenv: Generated POSIX console launchers interpret destination paths as shell syntax

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.

Record
BIT-virtualenv-2026-113722
Updated
2026-11-02
OSVCLSA-2026-1793107254 No score

TuxCare security update for virtualenv (8 CVEs)

TuxCare rebuilt virtualenv to address 8 CVEs. Fixed in 20.39.1.post5+tuxcare.

Record
CLSA-2026-1793107254
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-113722 No score

CVE-2026-113722 in virtualenv - Patched by Root

Root has patched CVE-2026-113722 in the virtualenv package for Root:PyPI. Multiple fixed versions available.

Record
ROOT-APP-PYPI-CVE-2026-113722
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
virtualenv
PyPI
before 21.14.9
21.14.9
python-virtualenv
Azure Linux:3
before 20.36.1-10
20.36.1-10
virtualenv
Bitnami
before 21.14.9
21.14.9
virtualenv
TuxCare:PyPI
From an advisory covering 8 CVEs
20.39.1 up to 20.39.1.post5+tuxcare, plus listed versions
20.39.1.post1+tuxcare20.39.1.post2+tuxcare20.39.1.post3+tuxcare20.39.1.post4+tuxcare
20.39.1.post5+tuxcare
python-virtualenv
Debian: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 less
20.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-virtualenv
Debian: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 less
20.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-virtualenv
Debian: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 less
20.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
virtualenv
PyPI
before 21.14.9, plus listed versions
0.80.8.10.8.20.8.30.8.4
Show 45 moreShow less
0.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.9
virtualenv
Root:PyPI
before 20.26.6+aikido.5
20.26.6+aikido.521.14.5+aikido.221.3.2+aikido.321.7.1+aikido.321.4.3+aikido.221.13.0+aikido.121.7.5+aikido.421.14.1+aikido.121.7.9+aikido.321.9.0+aikido.121.11.1+aikido.121.7.10+aikido.421.12.1+aikido.121.7.8+aikido.321.14.6+aikido.221.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.12.1+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-virtualenv
Ubuntu: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
Affected packages
PackageAffectedFixed
python-virtualenv
Ubuntu: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 less
15.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-virtualenv
Ubuntu:18.04:LTS
All versions, plus listed versions
15.1.0+ds-115.1.0+ds-1.1
None known
python-virtualenv
Ubuntu: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-virtualenv
Ubuntu: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-virtualenv
Ubuntu: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-virtualenv
Ubuntu:26.10
All versions, plus listed versions
20.36.1+ds-121.4.1+ds-121.5.1+ds-1
None known
python-virtualenv
Ubuntu: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-virtualenv
openSUSE:Tumbleweed
From an advisory covering 9 CVEs
before 21.15.1-1.1
21.15.1-1.1

History

History
RecordedChangedSources
affectedOSV
affected
factsOSV
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-113722 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.29%, the 21st percentile. Fixed in virtualenv 21.14.9.

References

Show 14 moreShow less
This page doesn't list everything

Left out here: 254 versions and the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open