A seemingly innocuous machine learning file can now be used to steal your SSH keys, cloud credentials, and other sensitive data—all without triggering any alarms. Microsoft has disclosed a critical vulnerability (CVE-2025-12058) in the popular Keras deep learning framework that allows attackers to craft model archives that, when loaded, silently read local files or make network requests to internal cloud metadata services. Even enabling Keras’s “safe mode” does not stop the attack, leaving millions of AI practitioners, developers, and automated pipelines exposed.
What Exactly Is the Vulnerability?
Keras models are typically saved in a .keras format, which is just a ZIP archive containing a model configuration file (config.json), weight data, and other metadata. When you load a model with keras.saving.loadmodel(), Keras reads this JSON file and reconstructs the neural network layer by layer. For certain layer types—like StringLookup, IndexLookup, and IntegerLookup—the configuration can include a vocabulary parameter. Normally, this is an inline list of tokens, but it can also be a string pointing to an external file path or URL.
The problem: during deserialization, Keras uses TensorFlow’s filesystem API (tf.io.gfile) to open and read that path immediately, without checking whether it’s a local file or a remote resource. An attacker can plant a path like /home/user/.ssh/idrsa or file:///etc/passwd in the vocabulary field, and the victim’s machine will hand over the contents as if they were part of the model. Worse, if the path is a URL such as http://169.254.169.254/latest/meta-data/—the well-known cloud metadata endpoint—the host will make an outbound request, potentially exposing temporary cloud credentials.
Crucially, this behavior occurs even when safemode=True is passed to loadmodel(). That setting is supposed to prevent arbitrary code execution during deserialization, but because the file read is handled by a built-in function—not deserialized from the model—safe mode doesn’t block it. According to Microsoft’s advisory, the flaw exists in Keras versions older than the October 2025 patch batch; however, due to conflicting reports about exact version numbers, administrators should simply upgrade to the latest stable release.
Who Is Affected and What’s at Stake?
This vulnerability cuts across every group that touches Keras models.
- Everyday users and hobbyists: If you’ve ever downloaded a pre-trained model from a public hub like Kaggle or Hugging Face, you could be at risk. A poisoned model can expose your personal files—think private keys, cryptocurrency wallets, or browser password stores—simply by loading it in a Jupyter notebook.
- Developers and power users: Many developers run models inside environments that have access to source code repositories, CI/CD secrets, and development databases. A malicious model embedded in a sample project or a seemingly helpful tutorial could extract GitHub tokens, API keys, or environment variables, leading to full repository compromise.
- IT professionals and system administrators: If your organization uses automated pipelines to train, test, or deploy AI models, an attacker can target those pipelines with a poisoned model. In cloud environments, an SSRF attack can fetch instance metadata credentials, enabling lateral movement to other services. The attack requires no user interaction beyond the pipeline loading the model, making it a potent supply chain threat.
How We Got Here: A Timeline of the Flaw
The root cause is a design decision made years ago when Keras introduced the .keras format. The idea was that lookup layers could reference an external vocabulary file instead of embedding it, to save space and support very large vocabularies. While convenient, this feature never enforced any restrictions on what paths could be used, and the safemode flag was never designed to intercept filesystem access.
The flaw was reported to Microsoft (which maintains Keras under the TensorFlow project) and assigned CVE-2025-12058. On October 17, 2025, Microsoft published an advisory describing the vulnerability and the patches. The fix changes how vocabulary files are handled: when saving a model, the actual file content is now embedded into the archive rather than storing a reference to the file system. When loading in safemode=True, any attempt to resolve an external file is blocked. These changes ensure that saved models are self-contained and cannot lead to unwanted data exfiltration during loading.
Exact patched version numbers have varied across advisories and package mirrors. Some trackers list a point release as the fix, while others point to a subsequent minor version bump. To be safe, the Keras project recommends updating to the latest available stable version, which incorporates the fixes as of late 2025. Checking your current version with pip show keras and upgrading with pip install --upgrade keras is the quickest way to ensure you’re protected.
What You Need to Do Now
Here are concrete steps you can take immediately, whether you’re an individual practitioner or managing a team.
1. Stop Loading Untrusted Models
Treat every .keras file from an unfamiliar source as potentially malicious. Even if it comes from a well-known repository, verify its integrity before loading it.
2. Upgrade Keras Immediately
Run pip install --upgrade keras to pull the latest release. If you’re using a virtual environment or a container image, rebuild with the new version. Check your current version: pip show keras. Any version prior to the October 2025 release should be considered vulnerable.
3. Scan Models Before Loading
Before calling loadmodel(), you can manually inspect the model archive. Here’s a quick Python snippet to check for suspicious vocabulary entries:
import zipfile, jsondef issuspiciousvocabulary(value):
if isinstance(value, str):
# Flag any path-like strings or URLs
return value.startswith('/') or '://' in value
return False
def scankerasmodel(filepath):
with zipfile.ZipFile(filepath, 'r') as zf:
config = json.loads(zf.read('config.json'))
# Recursively search for vocabulary fields
# This is a simplified check; layer configurations may be nested
for layer in config.get('config', {}).get('layers', []):
classname = layer.get('classname', '')
layerconfig = layer.get('config', {})
vocab = layerconfig.get('vocabulary', [])
if classname in ('StringLookup', 'IndexLookup', 'IntegerLookup'):
if issuspiciousvocabulary(vocab):
print(f"ALERT: Suspicious vocabulary in {classname}: {vocab}")
return False
return True
Usage
if not scankeras_model('model.keras'):
print("Do not load this model!")
For production pipelines, integrate such checks into your CI/CD system and automatically reject any model that references external file paths or URLs.
4. For Administrators: Harden Your Infrastructure
- Use sandboxing: Load all third-party models inside isolated containers or virtual machines with no access to sensitive filesystems and no network egress, except to explicitly allowed hosts. Tools like Docker, gVisor, or Firecracker can help.
- Restrict cloud metadata access: In cloud environments, use instance metadata service v2 (which requires a session token) or disable metadata access entirely for model-loading processes.
- Implement model signing and verification: Only accept models that have been signed by a trusted entity. Use checksums and digital signatures to verify integrity before loading.
- Disable unnecessary TensorFlow plugins: If you don’t need HTTP or cloud storage filesystem handlers, avoid installing optional packages like TensorFlow-IO that extend
tf.io.gfile’s capabilities. - Rotate credentials: If you’ve loaded any untrusted model before applying these mitigations, assume compromise. Rotate all SSH keys, API tokens, and cloud IAM credentials that might have been accessible from the host.
5. Monitor and Audit
Enable logging of file and network activity during model loading. Any unexpected file opens or outbound connections should trigger an alert and an immediate investigation.
The Bigger Picture: Securing the AI Supply Chain
CVE-2025-12058 is not an isolated incident—it’s a wake-up call. Machine learning model files are no longer inert data; they are active objects that can execute or trigger I/O during deserialization. Just as Office documents once became vectors for macro viruses, today’s model files are the new attack surface in the AI supply chain.
The fix from Keras is a step forward, but it only addresses one specific layer type. Other serialization risks remain, from pickle-based exploits to code execution via custom layers. The industry needs a broader shift toward treating model artifacts as untrusted executables: mandating provenance attestation, static analysis, and runtime sandboxing as standard practice.
Organizations that deploy AI should now add model scanning to their software bill of materials (SBOM) and treat model loading with the same caution they apply to opening a binary executable from the internet. The tools and processes to do this are still maturing, but the alternative—blindly trusting every .keras file that lands in your pipeline—is no longer tenable.
Keep an eye on the Keras GitHub repository and the Microsoft Security Response Center for any follow-up advisories. As model sharing becomes ubiquitous, expect more vulnerabilities that blur the line between a harmless download and a full-blown breach.