CVE-2026-102938: virtualenv writes prompt values into pyvenv.cfg without sanitizing line boundaries, allowing configuration injection

Published Sep 29, 2026
·
Updated

Summary

pyvenv.cfg is a line-based format with no escape syntax. PyEnvCfg.write() wrote values verbatim, while PyEnvCfg.readvalues() parses the file with str.splitlines(). A value containing a line boundary therefore became additional configuration lines, and because reading is last-wins, the injected keys replaced any key written earlier in the file.

Impact

The prompt value is the reachable input: it is set by --prompt, by the VIRTUALENVPROMPT environment variable, or from the config file, and write() emits prompt before home. A crafted prompt can therefore set home in the generated pyvenv.cfg:

console $ virtualenv --prompt $'x"\nhome = /attacker/path\nprompt = "z' venv $ grep '^home' venv/pyvenv.cfg home = /attacker/path

home is what tooling reads to locate the base interpreter, so a consumer that trusts it can be pointed elsewhere. implementation, versioninfo, version, executable, command and virtualenv are also written before prompt and can be replaced the same way.

This requires the prompt to come from somewhere other than the person running the command, for example a CI job templating a branch name into it, tooling deriving an environment name from user-supplied data, or an inherited VIRTUALENVPROMPT. Where the operator supplies the prompt directly they already control the command line, and the effect is corruption rather than privilege gain: the value is truncated at the boundary and read back with a dangling quote.

Details

The boundary set is the one str.splitlines() recognizes, which is wider than \n: \r, \v, \f, the file, group and record separators, U+0085, U+2028 and U+2029 were all written through unchanged and all split the line when read back.

Patches

PyEnvCfg.write() now collapses those boundaries to spaces as it serializes each line, so it cannot emit a structurally invalid file regardless of what a caller places in content.

Workarounds

Do not pass externally influenced data as the virtualenv prompt. Strip line boundaries from any value before using it as --prompt or VIRTUALENVPROMPT.

Other sources

virtualenv is a tool for creating isolated virtual python environments. Prior to 21.7.11, PyEnvCfg.write() writes prompt values verbatim to the line-oriented pyvenv.cfg format while PyEnvCfg.readvalues() parses the file with str.splitlines() and accepts the last value for duplicate keys. An attacker who influences --prompt, VIRTUALENVPROMPT, or configuration input can insert a recognized line boundary and additional keys, including home, causing consumers to use an attacker-selected base interpreter or corrupted environment metadata. The security impact requires prompt input from outside the operator's trust boundary; directly supplied prompt content primarily corrupts the operator's own environment. This issue is fixed in version 21.7.11.

— NVD

virtualenv writes prompt values into pyvenv.cfg without sanitizing line boundaries, allowing configuration injection

— Microsoft

Affected Software

2 affected componentsFixes available
pypi/virtualenv<21.7.11
pip/virtualenv<=21.7.10
21.7.11

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/virtualenv to a version that resolves this vulnerability.

    Fixed in 21.7.11
  2. Upgrade

    Upgrade virtualenv to a version that resolves this vulnerability.

    Fixed in 21.7.11
  3. Compensating control

    Do not pass externally influenced data as the virtualenv prompt; strip all line boundaries recognized by str.splitlines() from values before using them as --prompt or VIRTUALENV_PROMPT.

Event History

Sep 29, 2026
CVE Published
via MITRE·08:58 PM
Data Sourced
via MITRE·08:58 PM
DescriptionWeakness
Data Sourced
via NVD·09:17 PM
DescriptionSeverityWeakness
Sep 30, 2026
Advisory Published
via GitHub·11:53 PM
Data Sourced
via GitHub·11:53 PM
DescriptionWeaknessAffected Software
Oct 3, 2026
Data Sourced
via Microsoft·08:40 AM
DescriptionSeverityWeakness

Frequently Asked Questions

1

Which deployments are meaningfully exposed to this issue?

Deployments are meaningfully exposed when the value used for the virtual environment prompt crosses an operator trust boundary. This includes prompt values influenced through --prompt, VIRTUALENV_PROMPT, or configuration input; an operator supplying their own prompt primarily risks corrupting their own environment.

2

What can an attacker inject through a controlled prompt value?

An attacker can include a recognized line boundary followed by additional pyvenv.cfg keys. Because duplicate keys are resolved using the last value, this can inject values such as home and cause consumers to use an attacker-selected base interpreter or corrupted environment metadata.

3

What version fixes the issue?

The issue is fixed in virtualenv version 21.7.11. Versions prior to 21.7.11 are affected when untrusted input can reach the prompt value.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203