CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-113718

CVE-2026-113718: Code Injection in pypa/virtualenv XonshActivator via Multibyte Encoding Misalignment

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 24, 2026·5 min read·6 visits

Executive Summary (TL;DR)

Legacy multibyte encodings swallow escaping backslashes in virtualenv xonsh activation scripts, leading to shell literal breakout and code injection.

A code injection vulnerability in pypa/virtualenv prior to version 21.14.9 allows arbitrary command execution in xonsh shells using legacy multibyte encodings when sourcing activate.xsh.

Vulnerability Overview

pypa/virtualenv is a foundational component of the Python ecosystem used to generate isolated virtual environments. When initializing an environment, virtualenv writes shell-specific activation scripts such as activate.xsh for xonsh shells. These scripts embed metadata including environment destination paths and custom prompt titles supplied during creation.

Prior to version 21.14.9, virtualenv formatted prompt names and path literals using Python's repr() function inside XonshActivator.quote(). This implementation allowed non-ASCII UTF-8 characters to be formatted directly into generated activation scripts.

When xonsh parses the resulting script on systems configured with legacy multibyte character encodings (such as GBK, CP932, or Big5 via $XONSH_ENCODING), character decoding misalignment occurs. An attacker who controls virtual environment prompts or installation target directory names can inject arbitrary xonsh or Python code that executes when the target user sources activate.xsh.

Root Cause Analysis

The vulnerability resides in string literal quoting within XonshActivator.quote(). The xonsh shell treats activate.xsh activation files as executable Python source code. To escape dynamic values embedded in template files, XonshActivator.quote() relied on repr(string).

When repr() processes non-ASCII strings in Python 3, it outputs printable non-ASCII characters directly as raw UTF-8 bytes while escaping single quotes and special control bytes using a backslash (\, byte 0x5C). If xonsh executes on a system where $XONSH_ENCODING specifies a multibyte encoding, it decodes activate.xsh using that multibyte decoder rather than UTF-8.

In multibyte character encodings like GBK, certain non-ASCII UTF-8 character byte sequences contain trailing bytes equal to 0x5C. The legacy decoder combines the preceding character byte with the 0x5C backslash byte, processing both as a single double-byte character. Consequently, the backslash is swallowed during decoding and fails to escape the subsequent quote (0x27). The string literal terminates prematurely, causing remaining input bytes to be evaluated as arbitrary statements.

Code Analysis & Patch Assessment

In src/virtualenv/activation/xonsh/__init__.py, the original static method quote() delegated string quoting directly to repr():

# Unpatched implementation
@staticmethod
def quote(string: str) -> str:
    """Quote as a Python literal — xonsh parses the activation script as Python."""
    return repr(string)

To resolve this vulnerability, commit e5fc2e6e189a877ff559af288919e3525d13e5e0 replaced repr(string) with ascii(string):

# Patched implementation
@staticmethod
def quote(string: str) -> str:
    """Keep literals independent of the encoding xonsh uses to read the script."""
    return ascii(string)

By utilizing ascii(), all non-ASCII characters are explicitly converted into 7-bit ASCII escape sequences (such as \uXXXX or \xXX). Because the generated output consists exclusively of 7-bit ASCII bytes (0x00–0x7F), no character byte can be paired as a multibyte lead byte in encodings like GBK or Big5. This eliminates backslash-swallowing and secures literal boundaries across all target decoders.

Exploitation Methodology

Exploitation requires supplying a crafted non-ASCII string as either the virtual environment target path or the --prompt parameter during environment creation.

When virtualenv builds the environment, XonshActivator.quote() writes the input string containing non-ASCII characters into activate.xsh. The input sequence is chosen such that its raw UTF-8 byte sequence ends in a byte that pairs with 0x5C when interpreted under GBK.

When the victim sources activate.xsh inside a xonsh session configured with a legacy $XONSH_ENCODING, the multibyte decoder consumes the backslash as part of a double-byte character. The quote character remains unescaped, breaking out of the path or prompt literal. Subsequent bytes are interpreted directly as executable xonsh commands with the permissions of the user.

Impact Assessment

Successful exploitation of CVE-2026-113718 grants arbitrary code execution in the shell context of the user sourcing the activate.xsh script. The vulnerability carries a CVSS v4.0 base score of 7.1 (High) with vector string CVSS:4.0/AV:L/AC:H/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N.

Exploitation depends on specific preconditions, including local script execution and active multibyte legacy encodings in $XONSH_ENCODING. However, the direct confidentiality, integrity, and availability impacts are high if triggered within vulnerable user sessions.

No active exploitation has been recorded in CISA KEV, and the EPSS score is 0.00142 (3.23 percentile). Nonetheless, development environments utilizing xonsh in non-UTF-8 locales remain exposed until updated.

Remediation & Detection Guidance

To remediate CVE-2026-113718, upgrade virtualenv to version 21.14.9 or higher:

pip install --upgrade virtualenv

Upgrading the package does not retroactively modify existing activate.xsh files on disk. Previously generated virtual environments must be re-created or regenerated using patched virtualenv releases.

To audit disk storage for vulnerable files, check activate.xsh scripts for unescaped, non-ASCII UTF-8 bytes in variable definitions. Patched scripts represent non-ASCII input exclusively via ASCII escape sequences (e.g., \uXXXX).

Official Patches

pypaGitHub Security Advisory GHSA-394h-qwmc-48pf
pypaPull Request #3432: Use ascii() instead of repr() for xonsh quoting

Fix Analysis (1)

Technical Appendix

CVSS Score
7.1/ 10
CVSS:4.0/AV:L/AC:H/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
EPSS Probability
0.14%
Top 97% most exploited

Affected Systems

pypa/virtualenv < 21.14.9xonsh shell activation environments using legacy multibyte encodings ($XONSH_ENCODING)

Affected Versions Detail

Product
Affected Versions
Fixed Version
virtualenv
pypa
< 21.14.921.14.9
AttributeDetail
CWE IDCWE-94
Attack VectorLocal
CVSS v4.0 Score7.1 (High)
EPSS Score0.00142 (3.23 percentile)
Vulnerability ImpactCode Injection / Command Execution
Exploit AvailabilityNo Public Exploit
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
T1203Exploitation for Client Execution
Execution
CWE-94
Improper Control of Generation of Code ('Code Injection')

The software constructs all or part of a code segment using externally-influenced input, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.

Vulnerability Timeline

Fix committed in Pull Request #3432
2026-10-17
virtualenv 21.14.9 released and CVE-2026-113718 advisory published
2026-10-20

References & Sources

  • [1]GHSA-394h-qwmc-48pf Advisory
  • [2]Fix Commit e5fc2e6e189a877ff559af288919e3525d13e5e0
  • [3]Pull Request #3432
  • [4]Virtualenv Release Tag 21.14.9
  • [5]NVD Vulnerability Detail
  • [6]CVE.org CVE Record

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•CVE-2026-113723
7.1

CVE-2026-113723: OS Command Injection via Unsafe Prompt Expansion in PyPA virtualenv

A command injection vulnerability in PyPA virtualenv prior to version 21.14.9 allows local attackers to execute arbitrary commands when a user sources a generated shell activation script containing a crafted prompt value.

Alon Barad
Alon Barad
1 views•5 min read
•about 2 hours ago•CVE-2026-113720
4.4

CVE-2026-113720: Local Permission Inheritance Vulnerability in virtualenv

virtualenv prior to version 21.14.9 contains a local permission inheritance vulnerability in its app-data copy seeder. Due to the reliance on Python's standard shutil.copy() function, permissions from cached packages are replicated directly onto newly created virtual environment files, ignoring the active process umask and allowing unprivileged local attackers to inject code.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 4 hours ago•CVE-2026-113714
2.3

CVE-2026-113714: Cache Poisoning and Unvalidated Wheel Download in virtualenv

Prior to version 21.14.9, virtualenv downloads wheel files directly into its reusable persistent cache directory prior to verifying PyPI digests or compatibility. Combined with unsanitized stdout parsing from pip, a controlled package index can cause virtualenv to calculate digests against pre-existing local files while leaving unverified archives in the shared persistent cache.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 5 hours ago•CVE-2026-113717
2.3

CVE-2026-113717: Package Digest Verification Bypass in virtualenv Pip Seeder

A verification bypass vulnerability in virtualenv allows unverified Python wheel installation when using pip seeding with the download flag. Affected versions fail to perform SHA-256 digest validation against PyPI metadata before invoking pip.

Alon Barad
Alon Barad
6 views•5 min read
•about 6 hours ago•CVE-2026-113713
4.4

CVE-2026-113713: Insecure Temporary File Symlink Handling in PyPA virtualenv

Insecure temporary file usage (CWE-377) in virtualenv app-data seeder creates dangling symlinks pointing to deleted temporary directories, allowing local attackers on shared systems to execute arbitrary code.

Amit Schendel
Amit Schendel
5 views•4 min read
•about 7 hours ago•CVE-2026-112937
6.1

CVE-2026-112937: Arbitrary Directory Deletion via TOCTOU Race Condition in filelock ReadWriteLock

A Time-of-Check Time-of-Use (TOCTOU) race condition in the Python `filelock` library (versions 4.1.0 to 4.2.0) allows local unprivileged attackers to cause arbitrary directory deletion by swapping file system targets during lock cleanup or dead owner sweeps.

Alon Barad
Alon Barad
7 views•5 min read