Every CVE Search/ Get API key

CVE-2026-113717

virtualenv: Pip seeding with download omits wheel digest verification

2.3 LowFix available

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.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
None
User interaction
Passive

What an attacker can affect

Confidentiality
Low
Integrity
Low
Availability
Low

Exploit likelihood

0.29%Unchanged since Oct 21, 2026
90%50%10%1%

What each source reports

CVE List Score used 2.3

virtualenv: Pip seeding with download omits wheel digest verification

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.

Record
CVE-2026-113717
CVSS 4.0
2.3 LowCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N
Weakness
CWE-494
Updated
2026-11-02
EUVDEUVD-2026-105298 2.3

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.

Record
EUVD-2026-105298
CVSS 4.0
2.3 LowCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-cx28-75q4-x26q 2.3

virtualenv: Pip seeding with download omits wheel digest verification

Summary

The pip seeder acquires bundled wheels with download=False and lets pip access the index when --download is selected. Index candidates on that path do not pass through virtualenv's wheel digest verification.

Anthropic's OSS Scanner reported this as ANT-2026-74ALJBUF in virtualenv-20261015-005, received on 15 October 2026.

Affected area

Wheel selection by the pip seeder when downloads are enabled.

Attacker-controlled input

The pip seeder and download option must be selected. The finding concerns the default-index digest-verification policy. Explicit custom-index settings already opt out of comparison against PyPI metadata; this patch retains that policy.

Affected code

The relevant 21.14.8 source is in pip seeder.

Mechanism

With --seeder pip --download, PipInvoke.get_pip_install_cmd() first calls get_wheel(download=False), so virtualenv's download_wheel() and verify_wheel_digest() are skipped. It then lets pip install consult the configured index. An index wheel with the same package and version as the bundled wheel can be selected without virtualenv comparing its SHA-256 with PyPI metadata. The default app-data seeder takes the verification path for the same option.

Reproduction and evidence

The scanner built a local index named in pip.conf that served a modified copy of the bundled pip wheel under the same filename. In the control run, virtualenv --download env-default rejected the wheel with a digest mismatch. In the second run, adding --seeder pip produced an environment whose installed pip/__init__.py matched the index wheel; env-pip/bin/pip --version ran the added line. The reproducer checked the installed bytes and marker before reporting BUG.

Both --seeder pip and --download are needed. The report used a non-PyPI index from pip.conf and left PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, and PIP_INDEX unset, so virtualenv's default-seeder PyPI comparison remained active. This does not establish index control in the default PyPI setup. The unchecked pip-seeder download path is older, while the comparison with the default seeder arose when digest verification was added in 21.7.12. PR #3430 acquires and verifies selected wheels before invoking pip with index lookup disabled.

Attack sequence

sequenceDiagram
    participant I as Index in pip.conf
    participant V as virtualenv PipInvoke
    participant P as pip install
    participant E as Seeded environment
    I->>V: serve modified pip wheel
    V->>V: get_wheel(download=False)
    V->>P: install with --download permitting index lookup
    P->>I: select same-version index wheel
    I->>E: modified pip installed without virtualenv digest check
    E->>E: later pip invocation runs added code
    Note over V,E: Default app-data seeder rejects the same digest

Reproducer files

The following files are from the scanner report for ANT-2026-74ALJBUF. 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 glob
import hashlib
import json
import os
import shutil
import subprocess
import sys
import zipfile

from virtualenv.seed.wheels.embed import get_embed_wheel

companions = "/tmp/repro.d"
work = "/tmp/repro-pip-seeder-download"
shutil.rmtree(work, ignore_errors=True)
os.makedirs(work)

# set up: the pip wheel virtualenv bundles, and PyPI's record of its sha256 (served by virtualenv_offline.py: no network)
bundled = get_embed_wheel("pip",…
Record
GHSA-cx28-75q4-x26q
CVSS 4.0
2.3 LowCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N
Weakness
CWE-494
Updated
2026-11-02
NVD 2.3

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.

Record
CVE-2026-113717
CVSS 4.0
2.3 LowCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Weakness
CWE-494
Updated
2026-11-02
OSV 2.3

virtualenv: Pip seeding with download omits wheel digest verification

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.

Record
CVE-2026-113717
CVSS 4.0
2.3 LowCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N
Weakness
CWE-494
Updated
2026-11-02
OSVDEBIAN-CVE-2026-113717 2.3

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.

Record
DEBIAN-CVE-2026-113717
CVSS 4.0
2.3 LowCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Updated
2026-11-02
Show 5 moreShow less
OSVGHSA-cx28-75q4-x26q 2.3

virtualenv: Pip seeding with download omits wheel digest verification

Summary

The pip seeder acquires bundled wheels with download=False and lets pip access the index when --download is selected. Index candidates on that path do not pass through virtualenv's wheel digest verification.

Anthropic's OSS Scanner reported this as ANT-2026-74ALJBUF in virtualenv-20261015-005, received on 15 October 2026.

Affected area

Wheel selection by the pip seeder when downloads are enabled.

Attacker-controlled input

The pip seeder and download option must be selected. The finding concerns the default-index digest-verification policy. Explicit custom-index settings already opt out of comparison against PyPI metadata; this patch retains that policy.

Affected code

The relevant 21.14.8 source is in pip seeder.

Mechanism

With --seeder pip --download, PipInvoke.get_pip_install_cmd() first calls get_wheel(download=False), so virtualenv's download_wheel() and verify_wheel_digest() are skipped. It then lets pip install consult the configured index. An index wheel with the same package and version as the bundled wheel can be selected without virtualenv comparing its SHA-256 with PyPI metadata. The default app-data seeder takes the verification path for the same option.

Reproduction and evidence

The scanner built a local index named in pip.conf that served a modified copy of the bundled pip wheel under the same filename. In the control run, virtualenv --download env-default rejected the wheel with a digest mismatch. In the second run, adding --seeder pip produced an environment whose installed pip/__init__.py matched the index wheel; env-pip/bin/pip --version ran the added line. The reproducer checked the installed bytes and marker before reporting BUG.

Both --seeder pip and --download are needed. The report used a non-PyPI index from pip.conf and left PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, and PIP_INDEX unset, so virtualenv's default-seeder PyPI comparison remained active. This does not establish index control in the default PyPI setup. The unchecked pip-seeder download path is older, while the comparison with the default seeder arose when digest verification was added in 21.7.12. PR #3430 acquires and verifies selected wheels before invoking pip with index lookup disabled.

Attack sequence

sequenceDiagram
    participant I as Index in pip.conf
    participant V as virtualenv PipInvoke
    participant P as pip install
    participant E as Seeded environment
    I->>V: serve modified pip wheel
    V->>V: get_wheel(download=False)
    V->>P: install with --download permitting index lookup
    P->>I: select same-version index wheel
    I->>E: modified pip installed without virtualenv digest check
    E->>E: later pip invocation runs added code
    Note over V,E: Default app-data seeder rejects the same digest

Reproducer files

The following files are from the scanner report for ANT-2026-74ALJBUF. 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 glob
import hashlib
import json
import os
import shutil
import subprocess
import sys
import zipfile

from virtualenv.seed.wheels.embed import get_embed_wheel

companions = "/tmp/repro.d"
work = "/tmp/repro-pip-seeder-download"
shutil.rmtree(work, ignore_errors=True)
os.makedirs(work)

# set up: the pip wheel virtualenv bundles, and PyPI's record of its sha256 (served by virtualenv_offline.py: no network)
bundled = get_embed_wheel("pip",…
Record
GHSA-cx28-75q4-x26q
CVSS 4.0
2.3 LowCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N
Weakness
CWE-494
Updated
2026-11-02
OSVUBUNTU-CVE-2026-113717 2.3

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.

Record
UBUNTU-CVE-2026-113717
CVSS 4.0
2.3 LowCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:P/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N
Updated
2026-11-02
OSVAZL-112586 No score

CVE-2026-113717 affecting package python-virtualenv 20.36.1-10

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.

Record
AZL-112586
Updated
2026-11-05
OSVBIT-virtualenv-2026-113717 No score

virtualenv: Pip seeding with download omits wheel digest verification

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.

Record
BIT-virtualenv-2026-113717
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

Affected products

Affected packages

Affected packages
PackageAffectedFixed
virtualenv
PyPI
before 21.14.9
21.14.9
python-virtualenv
Azure Linux:3
through 20.36.1-10 None known
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
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
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
Show 6 moreShow less
Affected packages
PackageAffectedFixed
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

History

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

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

In short

CVE-2026-113717 is a low vulnerability (CVSS 2.3) 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 22nd percentile. Fixed in virtualenv 21.14.9.

References

Show 5 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