Executive Summary
A configuration injection vulnerability exists in virtualenv, a widely-used tool for creating isolated Python environments. The vulnerability stems from improper handling of line boundaries in the pyvenv.cfg configuration file, allowing attackers to inject malicious settings through user-supplied input. By crafting specially-formatted prompt values, an attacker can redirect the base interpreter path to a malicious location, potentially leading to arbitrary code execution or unauthorized data access.
This advisory provides technical details, affected systems, detection methods, and actionable mitigation strategies for organizations using virtualenv in their Python development and deployment workflows.
Understanding the Vulnerability
How Configuration Injection Works
The pyvenv.cfg file uses a line-based format to store critical configuration parameters for Python virtual environments. The vulnerability arises from the way virtualenv handles the prompt value—a user-configurable setting that can be specified through multiple input vectors:
- The
--promptcommand-line option - The
VIRTUALENV_PROMPTenvironment variable - Configuration files passed during environment creation
The PyEnvCfg.write() method writes prompt values directly to the configuration file without sanitizing line boundary characters (newlines). When PyEnvCfg._read_values() parses the file using str.splitlines(), it interprets these injected line breaks as separate configuration entries, allowing attackers to add unauthorized key-value pairs.
Example of exploitation:
# Legitimate prompt value
--prompt="my-env"
# Malicious prompt value containing line injection
--prompt="my-env
home=/path/to/malicious/interpreter"
When written to pyvenv.cfg, this creates:
prompt = my-env
home = /path/to/malicious/interpreter
Why virtualenv Is Affected
The root cause lies in two design decisions:
- No escape syntax: The
pyvenv.cfgformat lacks an escape mechanism for special characters, making it impossible to safely include line breaks in values. - Direct input handling: User-supplied data is written to the configuration file without validation or sanitization of line boundary characters.
This combination creates a direct path from user input to configuration file manipulation, bypassing the intended configuration hierarchy.
The pyvenv.cfg File and Its Role
The pyvenv.cfg file is the configuration backbone of Python virtual environments. It stores critical settings including:
- home: The path to the base Python interpreter
- prompt: The virtual environment name displayed in shell prompts
- include-system-site-packages: Whether to include system packages
- version: The Python version used to create the environment
The home parameter is particularly sensitive, as it determines which Python interpreter executes code within the virtual environment. Redirecting this path to a malicious location effectively compromises the entire environment.
Which Systems Are at Risk
Affected Versions
All versions of virtualenv that utilize the PyEnvCfg.write() and PyEnvCfg._read_values() methods without proper line boundary sanitization are vulnerable. This includes:
- virtualenv 20.x and earlier
- Any custom or forked versions using the same vulnerable code patterns
Check your installed version:
pip show virtualenv
Vulnerable Components
The vulnerability affects:
- Direct virtualenv usage: Applications or scripts that create virtual environments programmatically
- Wrapper tools: Any tool that invokes virtualenv with user-supplied prompt values
- Automation frameworks: CI/CD systems, deployment tools, and orchestration platforms
- Development workflows: Teams using virtualenv in shared or multi-tenant environments
Common Deployment Scenarios
High-risk scenarios include:
- CI/CD Pipelines: Build systems that set
VIRTUALENV_PROMPTusing branch names, commit hashes, or user identifiers - Shared Development Servers: Multi-user systems where environment variables can be set by different users
- Container Orchestration: Kubernetes or Docker environments where environment variables are dynamically injected
- Automated Provisioning: Infrastructure-as-Code tools that create virtual environments with user-supplied parameters
- Web Applications: Applications that generate virtual environments based on user input
Real-World Attack Scenarios
CI/CD Pipeline Exploitation
Scenario: A development team uses GitLab CI to test Python packages. The CI configuration sets the virtual environment prompt to the branch name:
before_script:
- export VIRTUALENV_PROMPT=$CI_COMMIT_REF_NAME
- python -m virtualenv venv
An attacker creates a malicious branch with a name containing line injection:
feature/test
home=/tmp/malicious-python
When the CI pipeline runs, it creates a virtual environment with a redirected interpreter path. Subsequent test runs execute code from the attacker’s malicious Python installation.
Impact: Arbitrary code execution in the CI/CD environment, potential access to secrets, credentials, and source code.
Environment Variable Injection
Scenario: A shared development server allows users to set environment variables. An attacker with local access sets:
export VIRTUALENV_PROMPT="dev-env
home=/home/attacker/python-trap"
When other developers create virtual environments on this server, their environments are silently redirected to the attacker’s Python installation, which could be modified to log credentials or inject malicious packages.
Impact: Lateral movement, credential theft, supply chain compromise.
User Input Manipulation Attacks
Scenario: A web application allows users to create isolated Python environments for running user-submitted code. The application uses the username as the prompt:
prompt_value = request.form['username']
os.system(f'python -m virtualenv --prompt={prompt_value} user_env')
An attacker submits a username containing:
attacker
home=/var/www/malicious
The resulting virtual environment executes code using the attacker’s Python installation, potentially compromising the entire application.
Impact: Remote code execution, data exfiltration, application compromise.
Security Impact and Risk Assessment
Potential Consequences of Exploitation
Successful exploitation of this vulnerability can lead to:
- Arbitrary Code Execution: Malicious Python code executes with the privileges of the user running the virtual environment
- Supply Chain Compromise: Injected code could modify packages, inject backdoors, or steal credentials
- Data Exfiltration: Access to sensitive data processed by Python applications
- Privilege Escalation: In some scenarios, exploitation could lead to elevated privileges
- Lateral Movement: Compromised environments can be used as pivot points for further attacks
- Compliance Violations: Unauthorized code execution may violate regulatory requirements (HIPAA, PCI-DSS, etc.)
Severity Factors
The severity of this vulnerability varies based on:
- Input Control: Whether user input is involved in setting the prompt value
- Environment Sensitivity: The criticality of data processed in affected environments
- Privilege Level: The user account running the virtual environment
- Network Exposure: Whether the system is accessible to untrusted users
- Automation Level: How many virtual environments are created automatically
Who Is Most Vulnerable
Organizations at highest risk include:
- SaaS Providers: Platforms offering Python execution environments to users
- CI/CD-Heavy Organizations: Teams with extensive automation and dynamic environment creation
- Shared Development Infrastructure: Companies with multi-tenant development servers
- Research Institutions: Organizations running user-submitted code
- DevOps Teams: Infrastructure teams managing large-scale Python deployments
How to Detect This Vulnerability
Monitoring Configuration Files
Implement file integrity monitoring for pyvenv.cfg files:
# Find all pyvenv.cfg files in your system
find / -name "pyvenv.cfg" -type f 2>/dev/null
# Monitor for changes
auditctl -w /path/to/venv/pyvenv.cfg -p wa -k venv_config_changes
Look for suspicious patterns:
- Unexpected
homevalues pointing outside standard Python installation directories - Multiple configuration lines that shouldn’t exist
- Recent modifications to configuration files
homepaths pointing to user directories or temporary locations
Code Analysis Techniques
Use static analysis to identify vulnerable patterns:
# Vulnerable pattern - direct user input to virtualenv
import subprocess
user_prompt = request.args.get('prompt')
subprocess.run(['python', '-m', 'virtualenv', f'--prompt={user_prompt}', 'venv'])
# Vulnerable pattern - environment variable without sanitization
os.environ['VIRTUALENV_PROMPT'] = branch_name
subprocess.run(['python', '-m', 'virtualenv', 'venv'])
Implement code scanning rules to detect:
- Direct use of user input in virtualenv commands
- Unsanitized environment variables passed to virtualenv
- Missing input validation for prompt values
Log Indicators to Watch For
Monitor for these indicators of exploitation:
- Unexpected Python interpreter paths in virtual environment configurations
- Virtualenv creation with unusual prompt values containing special characters
- Changes to
pyvenv.cfgfiles outside of expected maintenance windows - Execution of Python code from non-standard interpreter locations
- Failed imports or module loading errors suggesting interpreter redirection
Immediate Actions to Take

Apply Security Patches
Step 1: Update virtualenv immediately
# Upgrade to the latest patched version
pip install --upgrade virtualenv
# Verify the update
pip show virtualenv
The patched version modifies PyEnvCfg.write() to collapse line boundaries into spaces, preventing injection attacks.
Step 2: Verify the patch is applied
# Test that line injection is prevented
import subprocess
result = subprocess.run(
['python', '-m', 'virtualenv', '--prompt=test
home=/tmp', 'test_venv'],
capture_output=True
)
# In patched version, the newline is converted to a space
Sanitize User Input
Implement input validation for all prompt values:
import re
def sanitize_prompt(prompt_value):
"""Remove line boundary characters from prompt values"""
# Remove newlines, carriage returns, and other control characters
sanitized = re.sub(r'[\r
\x00-\x1f]', '', prompt_value)
# Limit length to prevent other attacks
sanitized = sanitized[:50]
# Allow only safe characters
if not re.match(r'^[a-zA-Z0-9\-_\.]+$', sanitized):
raise ValueError("Invalid prompt value")
return sanitized
# Usage
try:
safe_prompt = sanitize_prompt(user_input)
os.system(f'python -m virtualenv --prompt={safe_prompt} venv')
except ValueError as e:
# Handle invalid input
log_security_event(f"Invalid prompt input rejected: {e}")
Harden Your Environment
Environment variable controls:
# Restrict who can set VIRTUALENV_PROMPT
# In /etc/security/limits.conf or similar
# Prevent unprivileged users from setting environment variables
# Use environment variable whitelisting in CI/CD
# Only allow specific, validated variables
File permissions:
# Restrict write access to virtual environment directories
chmod 750 /path/to/venv
chmod 640 /path/to/venv/pyvenv.cfg
# Ensure only authorized users can create virtual environments
setfacl -m u:developer:rx /path/to/venv
Long-Term Protection Strategies
Input Validation Best Practices
Establish comprehensive input validation policies:
- Whitelist Approach: Define allowed characters and patterns for prompt values
- Length Limits: Restrict prompt values to reasonable lengths (e.g., 50 characters)
- Type Checking: Ensure input matches expected data types
- Encoding Validation: Verify input uses expected character encoding
class PromptValidator:
"""Comprehensive prompt validation"""
MAX_LENGTH = 50
ALLOWED_PATTERN = r'^[a-zA-Z0-9\-_\.]+$'
FORBIDDEN_CHARS = ['
', '\r', '\x00', '|', ';', '&', '$', '`']
@classmethod
def validate(cls, prompt):
# Check length
if len(prompt) > cls.MAX_LENGTH:
raise ValueError("Prompt exceeds maximum length")
# Check for forbidden characters
if any(char in prompt for char in cls.FORBIDDEN_CHARS):
raise ValueError("Prompt contains forbidden characters")
# Check pattern
if not re.match(cls.ALLOWED_PATTERN, prompt):
raise ValueError("Prompt contains invalid characters")
return prompt
Access Control in Shared Environments
Implement strict access controls:
- User Isolation: Prevent users from accessing other users’ virtual environments
- Directory Permissions: Use restrictive umask settings (e.g.,
umask 0077) - SELinux/AppArmor: Implement mandatory access controls
- Container Isolation: Use containerization to isolate environments
# Set restrictive umask for virtual environment creation
umask 0077
python -m virtualenv venv
# Verify permissions
ls -la venv/pyvenv.cfg
# Should show: -rw------- (600)
Continuous Monitoring and Auditing
Establish ongoing security practices:
- Configuration Auditing: Regular reviews of
pyvenv.cfgfiles - Dependency Scanning: Monitor virtualenv for security updates
- Log Analysis: Automated analysis of virtualenv creation logs
- Penetration Testing: Regular testing of virtualenv usage in your environment
# Automated audit script
#!/bin/bash
echo "Auditing virtualenv configurations..."
find / -name "pyvenv.cfg" -type f 2>/dev/null | while read cfg; do
echo "Checking: $cfg"
# Check for suspicious home paths
if grep -q "^home = " "$cfg"; then
home_path=$(grep "^home = " "$cfg" | cut -d' ' -f3-)
if [[ ! "$home_path" =~ ^/usr/bin/python|^/usr/local/bin/python ]]; then
echo "WARNING: Suspicious home path in $cfg: $home_path"
fi
fi
# Check for unexpected configuration lines
line_count=$(wc -l < "$cfg")
if [ "$line_count" -gt 10 ]; then
echo "WARNING: Unusual number of configuration lines in $cfg"
fi
done
Resources and Support
Official Documentation
- virtualenv Official Repository: https://github.com/pypa/virtualenv
- Python Virtual Environments Guide: https://docs.python.org/3/tutorial/venv.html
- PEP 405 – Python Virtual Environments: https://www.python.org/dev/peps/pep-0405/
Security References
- NIST Secure Software Development Framework: https://csrc.nist.gov/projects/secure-software-development-framework
- OWASP Input Validation Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/InputValidationCheat_Sheet.html
- CWE-94: Improper Control of Generation of Code: https://cwe.mitre.org/data/definitions/94.html
Getting Help
- Report Security Issues: Contact the virtualenv security team through the official repository
- Community Support: Python Security Interest Group (python-security@python.org)
- Enterprise Support: Consult with your Python distribution provider (Red Hat, Canonical, etc.)
Frequently Asked Questions
Q: What is the main risk of this vulnerability?
A: Attackers can manipulate the pyvenv.cfg file to redirect the base interpreter path to a malicious location. This allows execution of untrusted code with the privileges of the user running the virtual environment, potentially leading to data theft, credential compromise, or system compromise.
Q: Which versions of virtualenv are vulnerable?
A: All versions using the PyEnvCfg.write() and PyEnvCfg._read_values() methods without proper line boundary sanitization are affected. This includes virtualenv 20.x and earlier. Check your version with pip show virtualenv and update immediately.
Q: How can attackers inject malicious configurations?
A: Through three primary vectors: the --prompt command-line option, the VIRTUALENV_PROMPT environment variable, or configuration files. By crafting input containing line boundary characters (newlines), attackers can add unauthorized configuration lines to the pyvenv.cfg file.
Q: What should I do immediately?
A: Take these steps in order: (1) Update virtualenv to the latest patched version, (2) Sanitize any user-supplied prompt values in your code, (3) Monitor your pyvenv.cfg files for unauthorized changes, (4) Review CI/CD pipelines for vulnerable patterns.
Q: Is this vulnerability exploitable in my CI/CD pipeline?
A: Yes, if your CI/CD pipeline sets VIRTUALENV_PROMPT using branch names, commit hashes, user identifiers, or other user-supplied data without sanitization. Review your pipeline configuration immediately and implement input validation.
Q: How do I verify if my systems are compromised?
A: Check pyvenv.cfg files for unexpected home values pointing outside standard Python installation directories, review recent configuration changes, audit environment variable settings, and check logs for unusual virtualenv creation patterns. Use the monitoring scripts provided in this advisory.
Q: Can this vulnerability be exploited remotely?
A: Direct remote exploitation requires the ability to influence virtualenv creation parameters. However, in web applications, CI/CD systems, or other automated environments that accept user input for prompt values, remote exploitation is possible.
Q: What’s the difference between this and other injection vulnerabilities?
A: This is a configuration injection vulnerability specific to the line-based format of pyvenv.cfg. Unlike command injection or code injection, it exploits the lack of escape syntax in the configuration file format, making it particularly difficult to defend against without proper input validation.
Q: Are virtual environments created before the patch applied still vulnerable?
A: No, the vulnerability exists in the creation process. However, if a malicious pyvenv.cfg was created before patching, it remains malicious. Audit existing virtual environments and recreate them with the patched version if necessary.
Q: How does this affect containerized environments?
A: In Docker and Kubernetes environments, if environment variables are dynamically injected based on user input, the vulnerability can be exploited. Implement the same input validation and sanitization practices in your container orchestration configurations.
Conclusion
The configuration injection vulnerability in virtualenv represents a significant risk to organizations using this tool for Python environment management. The vulnerability’s exploitability in CI/CD pipelines, shared development environments, and web applications makes it a priority for immediate remediation.
Organizations should prioritize updating virtualenv, implementing comprehensive input validation, and establishing ongoing monitoring practices. By following the guidance in this advisory, you can significantly reduce your exposure to this vulnerability and strengthen your overall Python security posture.
For questions or additional information, contact your security team or consult the official virtualenv security resources.
Document Version: 1.0
Last Updated: 2024
Classification: Security Advisory