CVE-2019-20477
📋 TL;DR
This vulnerability in PyYAML allows remote code execution through unsafe YAML deserialization. Attackers can exploit the load() and load_all() functions to execute arbitrary commands via the subprocess.Popen class. Any application using vulnerable PyYAML versions to parse untrusted YAML input is affected.
💻 Affected Systems
- PyYAML
📦 What is this software?
Fedora by Fedoraproject
Fedora by Fedoraproject
Pyyaml by Pyyaml
⚠️ Risk & Real-World Impact
Worst Case
Full system compromise with remote code execution leading to data theft, ransomware deployment, or complete system takeover.
Likely Case
Remote code execution allowing attackers to run arbitrary commands, install malware, or pivot to other systems.
If Mitigated
Limited impact if proper input validation and sandboxing prevent untrusted YAML parsing.
🎯 Exploit Status
Exploit code is publicly available and trivial to weaponize. No authentication required if application parses untrusted YAML.
🛠️ Fix & Mitigation
✅ Official Fix
Patch Version: PyYAML 5.2 and later
Vendor Advisory: https://github.com/yaml/pyyaml/blob/master/CHANGES
Restart Required: No
Instructions:
1. Upgrade PyYAML to version 5.2 or later using pip: pip install --upgrade pyyaml>=5.2
2. Verify the upgrade with: pip show pyyaml
3. Test application functionality after upgrade.
🔧 Temporary Workarounds
Replace unsafe load with safe_load
allReplace all instances of yaml.load() and yaml.load_all() with yaml.safe_load() and yaml.safe_load_all() in code.
# Code change example:
# Replace: data = yaml.load(input)
# With: data = yaml.safe_load(input)
Input validation and sanitization
allImplement strict input validation to reject untrusted YAML input or sanitize before processing.
# Example validation:
if not trusted_source(yaml_input):
raise ValueError('Untrusted YAML input rejected')
🧯 If You Can't Patch
- Implement network segmentation to isolate vulnerable systems
- Deploy application-level firewalls to block malicious YAML payloads
🔍 How to Verify
Check if Vulnerable:
Check PyYAML version with: python -c "import yaml; print(yaml.__version__)" and verify if between 5.1 and 5.1.2.
Check Version:
python -c "import yaml; print(yaml.__version__)"
Verify Fix Applied:
After upgrade, verify version is 5.2 or higher: python -c "import yaml; print(yaml.__version__)"
📡 Detection & Monitoring
Log Indicators:
- Unusual process spawns from Python applications
- Suspicious command execution patterns
- YAML parsing errors with malicious payloads
Network Indicators:
- Unusual outbound connections from Python processes
- Command and control traffic patterns
SIEM Query:
process.name:python AND process.cmdline:*Popen* OR process.cmdline:*subprocess*
🔗 References
- https://github.com/yaml/pyyaml/blob/master/CHANGES
- https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/33VBUY73AA6CTTYL3LRWHNFDULV7PFPN/
- https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/52N5XS73Z5S4ZN7I7R56ICCPCTKCUV4H/
- https://www.exploit-db.com/download/47655
- https://github.com/yaml/pyyaml/blob/master/CHANGES
- https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/33VBUY73AA6CTTYL3LRWHNFDULV7PFPN/
- https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/52N5XS73Z5S4ZN7I7R56ICCPCTKCUV4H/
- https://www.exploit-db.com/download/47655