CVE-2025-9906
📋 TL;DR
CVE-2025-9906 is a critical vulnerability in Keras that allows arbitrary code execution when loading specially crafted .keras model files. Attackers can bypass safe_mode=True protection by embedding malicious configuration that disables safe deserialization, then execute arbitrary Python code via Lambda layers. This affects any system using Keras to load untrusted model files.
💻 Affected Systems
- Keras
📦 What is this software?
Keras by Keras
⚠️ Risk & Real-World Impact
Worst Case
Complete system compromise with attacker gaining full control over the affected system, potentially leading to data theft, ransomware deployment, or lateral movement within networks.
Likely Case
Remote code execution on systems loading malicious Keras models from untrusted sources, enabling data exfiltration, backdoor installation, or cryptocurrency mining.
If Mitigated
Limited impact if models are only loaded from trusted sources with proper validation and sandboxing in place.
🎯 Exploit Status
Exploit requires creating a malicious .keras archive with specific file ordering but is straightforward for attackers with Python knowledge.
🛠️ Fix & Mitigation
✅ Official Fix
Patch Version: Version containing PR #21429 fix
Vendor Advisory: https://github.com/keras-team/keras/pull/21429
Restart Required: No
Instructions:
1. Update Keras to version containing PR #21429 fix. 2. Run: pip install --upgrade keras. 3. Verify safe_mode=True cannot be disabled via config.json in .keras archives.
🔧 Temporary Workarounds
Disable Lambda layer loading
allPrevent loading of Lambda layers which contain arbitrary Python code
Set environment variable: export KERAS_BACKEND_DISABLE_LAMBDA_LAYERS=1
Or in Python: os.environ['KERAS_BACKEND_DISABLE_LAMBDA_LAYERS'] = '1'
Validate model sources
allOnly load .keras files from trusted, verified sources with cryptographic signatures
🧯 If You Can't Patch
- Implement strict input validation to only accept .keras files from trusted sources with digital signatures
- Run Keras model loading in isolated containers or sandboxes with minimal privileges
🔍 How to Verify
Check if Vulnerable:
Check if Keras version predates PR #21429 fix by examining version and attempting to load a test malicious archive (in safe environment)
Check Version:
python -c "import keras; print(keras.__version__)"
Verify Fix Applied:
Test that safe_mode=True cannot be disabled via config.json and Lambda layers with pickled code are rejected
📡 Detection & Monitoring
Log Indicators:
- Failed model loading attempts with Lambda layer errors
- Unexpected enable_unsafe_deserialization() calls in logs
- Python process spawning unexpected child processes
Network Indicators:
- Downloads of .keras files from untrusted sources
- Outbound connections from Keras processes to suspicious IPs
SIEM Query:
Process creation where parent process contains 'keras' AND (command line contains 'python -c' OR network connection to external IP)