CVE-2026-31214: torch-checkpoint: unsafe pickle deserialization RCE

AWAITING NVD
Published May 12, 2026
CISO Take

The ml-engineering project's torch-checkpoint-shrink.py utility loads PyTorch checkpoint files using torch.load() without the weights_only=True guard, allowing embedded pickle payloads to execute arbitrary Python code the moment a checkpoint is processed. This is a classic unsafe deserialization pattern (CWE-502) applied to the ML supply chain: any engineer who runs this script against an untrusted or attacker-supplied .pt file hands over their workstation or CI runner to the attacker. EPSS is not yet scored and no public exploit exists, but the attack primitive is trivially reproducible — crafting a malicious pickle payload for torch.load() is well-documented and has powered prior ML-targeted attacks. Immediately audit all uses of this script; apply the one-line fix of setting weights_only=True in the torch.load() call, or migrate checkpoint workflows to safetensors format, which is pickle-free by design.

Sources: NVD ATLAS

Risk Assessment

Risk is HIGH for any team that has this script in a training pipeline or model management workflow, despite the absence of a CVSS score and KEV listing. The exploitability is trivial: crafting a malicious PyTorch checkpoint is a solved problem with public tooling (e.g., fickling). The blast radius is contained to users who actively invoke the script, but those users are typically ML engineers or automated CI/CD jobs running with elevated permissions. The lack of a CVSS score reflects publication lag, not low severity. The attack surface expands significantly in multi-tenant environments, shared model registries, or any pipeline that ingests third-party checkpoints.

Attack Kill Chain

Artifact Delivery
Attacker crafts a malicious PyTorch checkpoint (.pt) file with an embedded pickle payload and delivers it to the victim via a public model hub, email, or compromised shared model registry.
AML.T0058
User Execution
Victim engineer or automated CI job runs torch-checkpoint-shrink.py against the malicious file, trusting it as a legitimate model checkpoint.
AML.T0011.000
Deserialization RCE
torch.load() deserializes the pickle payload without restriction, executing arbitrary Python code in the context of the running process with the victim's OS-level privileges.
AML.T0018.002
Impact
Attacker achieves code execution on the training host or CI runner, enabling credential theft, model exfiltration, backdoor installation, or lateral movement to the broader ML infrastructure.
AML.T0025

Severity & Risk

CVSS 3.1
N/A
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
Trivial

Recommended Action

6 steps
  1. Immediate: Replace torch.load(f) with torch.load(f, weights_only=True) in torch-checkpoint-shrink.py at line

  2. This restricts deserialization to tensor data only and eliminates arbitrary pickle execution.

  3. Short-term: Audit all other scripts in your codebase and pipelines for torch.load() calls lacking weights_only=True; use grep -r 'torch.load' to enumerate them.

  4. Structural: Migrate checkpoint storage to safetensors format (pip install safetensors) — pickle-free, memory-safe, and faster to load.

  5. Detection: Deploy fickling (pip install fickling) in CI to scan .pt files for suspicious pickle opcodes before loading.

  6. Policy: Enforce code review gates on any script that deserializes model files from external or shared sources.

Classification

Compliance Impact

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity
ISO 42001
8.4 - AI system development Annex B.6.2 - AI supply chain risk management
NIST AI RMF
GOVERN 6.1 - Policies and procedures for AI risk management MANAGE 2.4 - Risks and their relevant impacts are prioritized, respond to, and managed
OWASP LLM Top 10
LLM03:2025 - Supply Chain

Frequently Asked Questions

What is CVE-2026-31214?

The ml-engineering project's torch-checkpoint-shrink.py utility loads PyTorch checkpoint files using torch.load() without the weights_only=True guard, allowing embedded pickle payloads to execute arbitrary Python code the moment a checkpoint is processed. This is a classic unsafe deserialization pattern (CWE-502) applied to the ML supply chain: any engineer who runs this script against an untrusted or attacker-supplied .pt file hands over their workstation or CI runner to the attacker. EPSS is not yet scored and no public exploit exists, but the attack primitive is trivially reproducible — crafting a malicious pickle payload for torch.load() is well-documented and has powered prior ML-targeted attacks. Immediately audit all uses of this script; apply the one-line fix of setting weights_only=True in the torch.load() call, or migrate checkpoint workflows to safetensors format, which is pickle-free by design.

Is CVE-2026-31214 actively exploited?

No confirmed active exploitation of CVE-2026-31214 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-31214?

1. Immediate: Replace torch.load(f) with torch.load(f, weights_only=True) in torch-checkpoint-shrink.py at line 57. This restricts deserialization to tensor data only and eliminates arbitrary pickle execution. 2. Short-term: Audit all other scripts in your codebase and pipelines for torch.load() calls lacking weights_only=True; use grep -r 'torch.load' to enumerate them. 3. Structural: Migrate checkpoint storage to safetensors format (pip install safetensors) — pickle-free, memory-safe, and faster to load. 4. Detection: Deploy fickling (pip install fickling) in CI to scan .pt files for suspicious pickle opcodes before loading. 5. Policy: Enforce code review gates on any script that deserializes model files from external or shared sources.

What systems are affected by CVE-2026-31214?

This vulnerability affects the following AI/ML architecture patterns: training pipelines, model serving, MLOps CI/CD, model registries.

What is the CVSS score for CVE-2026-31214?

No CVSS score has been assigned yet.

Technical Details

NVD Description

The torch-checkpoint-shrink.py script in the ml-engineering project in commit 0099885db36a8f06556efe1faf552518852cb1e0 (2025-20-27) contains an insecure deserialization vulnerability (CWE-502). The script uses torch.load() to process PyTorch checkpoint files (.pt) without enabling the security-restrictive weights_only=True parameter. This oversight allows the deserialization of arbitrary Python objects via the pickle module. A remote attacker can exploit this by providing a maliciously crafted checkpoint file, leading to arbitrary code execution in the context of the user running the script.

Exploitation Scenario

An adversary targets an ML engineer at a financial institution running distributed LLM fine-tuning. The attacker publishes a poisoned PyTorch checkpoint on a public model hub, mimicking a popular base model. The victim's pipeline uses torch-checkpoint-shrink.py to reduce checkpoint size before uploading to the internal model registry. When the script calls torch.load() on the attacker's file, the embedded pickle payload executes: it establishes a reverse shell to an attacker-controlled server, exfiltrates the SSH key from ~/.ssh/, and installs a persistent backdoor in site-packages. The attacker now has credentials to the internal training cluster and access to proprietary model weights.

Timeline

Published
May 12, 2026
Last Modified
May 12, 2026
First Seen
May 12, 2026

Related Vulnerabilities