PHP2Shell: Read our blog on the critical RCE vulnerabilities affecting 70% of the Internet
Vulnerability DatabaseCVE-2026-113716

CVE-2026-113716: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-113716 is a symlink-following vulnerability in the virtualenv Python environment creation tool (maintained by PyPA) that allows a local attacker to cause files to be written outside the intended virtual environment directory. The flaw exists in all versions prior to 21.14.9; the confirmed affected release is 21.14.8. It was reported by Anthropic's OSS Scanner as ANT-2026-MUFJEG11 on October 15, 2026, and publicly disclosed via a GitHub Security Advisory (GHSA-cw65-gx24-rc82) on October 17, 2026. The CVSS v3.1 base score is 4.5 (Medium) (GitHub Advisory, Red Hat CVE).

Technical details

The root cause is CWE-59 (Improper Link Resolution Before File Access / 'Link Following'). The builtin creator's ensure_dir() function uses Path.exists() to check whether a target directory exists before creating it; because exists() follows symbolic links, a pre-planted symlink at bin, lib, or any package directory component is accepted as a valid directory. When a victim user subsequently runs virtualenv targeting that location, the interpreter files, seed packages (pip, activate scripts), and .pth files are written through the symlink into whatever directory it points to — potentially outside the environment tree (e.g., ~/.local/bin). The attack requires a second local account to pre-create the symlink tree before the victim invokes virtualenv; the written bytes are virtualenv's own environment-creation output, not arbitrary attacker-chosen content. The fix (PR #3429) introduces ensure_within(), which uses lstat() to inspect each path component without following links, removes any symlink or Windows junction found, and creates a real directory in its place (GitHub Advisory, Fix PR).

Impact

A local attacker who can write to a shared or world-writable parent directory can plant symlinks that redirect virtualenv's output (interpreter binaries, pip launchers, activation scripts, and .pth files) into directories on the victim's PATH such as ~/.local/bin. This enables the attacker to place executable files and malicious .pth code that runs when the victim subsequently invokes pip or any seeded tool, achieving code execution under the victim's account. Confidentiality, integrity, and availability are all assessed as Low impact in the CVSS scoring, reflecting that the written content is environment-creation output rather than arbitrary attacker-chosen bytes, and that exploitation requires specific local preconditions (GitHub Advisory).

Exploitability

There is no public proof-of-concept exploit and no evidence of in-the-wild exploitation as of the disclosure date (Feedly). The EPSS score is 0.0, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities catalog. Exploitation requires local access, a low-privileged account, high attack complexity (the attacker must pre-stage the symlink tree before the victim creates the environment), and the victim must have access to the attacker-controlled linked destination. The vulnerability was discovered through automated scanning (Anthropic's OSS Scanner) rather than active exploitation (GitHub Advisory).

Exploitation steps

  1. Reconnaissance: Identify a shared or world-writable directory where a target user is likely to create a Python virtual environment (e.g., a shared project checkout directory such as ~/project).
  2. Prepare the malicious directory tree: As the attacker account, create the expected virtualenv structure under the target path, planting a symlink at the bin directory component pointing to a location on the victim's PATH: mkdir -p ~/project/venv/lib/python3.X/site-packages && ln -s ../../.local/bin ~/project/venv/bin.
  3. Plant a malicious .pth file: Write a payload .pth file into the pre-created site-packages directory: echo "import os; open(os.path.expanduser('~/PWNED'), 'w').write('pwned')" > ~/project/venv/lib/python3.X/site-packages/payload.pth. This file will be written into the victim's environment and loaded when Python starts.
  4. Wait for victim to create the environment: When the victim runs virtualenv --no-periodic-update venv inside ~/project, ensure_dir() accepts the existing venv/bin symlink and writes python*, pip*, and activate* through it into ~/.local/bin.
  5. Trigger payload execution: When the victim subsequently runs pip --version (or any tool from ~/.local/bin), the Python interpreter loads the planted .pth file from the seeded site-packages, executing the attacker's payload under the victim's account (GitHub Advisory).

Indicators of compromise

  • File System: Unexpected files (python*, pip*, activate*) appearing in ~/.local/bin or other user PATH directories that were not explicitly installed by the user; presence of .pth files with unusual content (e.g., import os; open(...)) in virtualenv site-packages directories; symlinks at venv/bin, venv/lib, or venv/lib/pythonX.Y pointing outside the environment tree.
  • Logs: virtualenv warning messages containing replace environment directory link <path> in application logs (emitted by the patched version when it detects and removes a pre-existing symlink — absence of these warnings on an unpatched system is itself a risk indicator).
  • Process: Unexpected file creation events (e.g., creation of a marker file like ~/PWNED) triggered by running pip --version or other seeded tools; Python processes loading .pth files from unexpected locations (GitHub Advisory).

Mitigation and workarounds

Upgrade virtualenv to version 21.14.9 or later, which replaces ensure_dir() with ensure_within() to detect and remove symlinks/junctions before creating environment directories (Release 21.14.9, Fix Commit). As a workaround where upgrading is not immediately possible, always create virtual environments in fresh directories under a parent directory controlled exclusively by the invoking user — never reuse or create environments in directories that another account can write to. Avoid creating environments in shared project checkouts or world-writable locations. The --clear flag removes a pre-planted tree before creation, but this is not a reliable mitigation since the attacker can re-plant after the clear (GitHub Advisory).

Community reactions

The vulnerability was reported by Anthropic's OSS Scanner (ANT-2026-MUFJEG11), reflecting growing use of automated security scanning tools against open-source Python tooling. The maintainer (gaborbernat) responded promptly, merging the fix (PR #3429) on October 17, 2026 — the same day as the advisory publication — and releasing version 21.14.9 the same day. Red Hat tracked the issue via Bugzilla (#2556400) and published a CVE advisory shortly after. Community discussion was limited given the moderate severity and local-only attack vector (GitHub Advisory, Fix PR).

Additional resources

Linux Distribution fix status

Fix availability across major Linux distributions and their releases.

RHEL / CentOS

Affected

OpenShift

python-virtualenv.src

Affected

Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-c978-59m8-c77vHIGH7.8
  • Python logoPython
  • virtualenv
NoYesOct 21, 2026
GHSA-cw65-gx24-rc82MEDIUM4.5
  • Python logoPython
  • virtualenv
NoYesOct 21, 2026
CVE-2026-113716MEDIUM4.5
  • Python logoPython
  • virtualenv
NoYesOct 21, 2026
GHSA-43mp-35q3-x3fqMEDIUM4.5
  • Python logoPython
  • virtualenv
NoYesOct 21, 2026
CVE-2026-113724MEDIUM4.5
  • Python logoPython
  • virtualenv
NoYesOct 21, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management