CVE-2026-31221 Overview
CVE-2026-31221 is an insecure deserialization vulnerability [CWE-502] in PyTorch-Lightning versions 2.6.0 and earlier. The LightningModule.load_from_checkpoint() method internally calls torch.load() without setting the weights_only=True parameter. This default behavior permits deserialization of arbitrary Python objects through the Pickle module. An attacker who supplies a malicious checkpoint file can trigger arbitrary code execution when a victim loads that file. The flaw affects machine learning workflows that consume third-party model checkpoints, including pretrained models shared via public repositories or model hubs.
Critical Impact
Loading an untrusted PyTorch-Lightning checkpoint results in arbitrary code execution with the privileges of the running process, compromising confidentiality, integrity, and availability of the host.
Affected Products
- PyTorch-Lightning 2.6.0 and earlier (Python package)
- LightningModule.load_from_checkpoint() API consumers
- Lightning AI training and inference pipelines using torch.load() defaults
Discovery Timeline
- 2026-05-12 - CVE-2026-31221 published to NVD
- 2026-05-15 - Last updated in NVD database
Technical Details for CVE-2026-31221
Vulnerability Analysis
PyTorch-Lightning relies on PyTorch's serialization layer to persist and restore model state. The framework's LightningModule.load_from_checkpoint() helper wraps torch.load() to reconstruct model weights, optimizer states, and hyperparameters from a .ckpt file. PyTorch's default deserializer uses Python's pickle module, which can instantiate arbitrary objects and invoke methods such as __reduce__ during unpickling. When a checkpoint contains attacker-controlled pickle opcodes, those opcodes execute as Python code the moment the file is loaded. The attack does not require the model to run inference; the act of loading the checkpoint is sufficient.
Root Cause
The root cause is the omission of the weights_only=True argument when PyTorch-Lightning invokes torch.load(). PyTorch introduced weights_only to restrict deserialization to tensor data and a small allowlist of safe types. Because Lightning does not pass this flag, the underlying call falls back to unrestricted pickle deserialization. Any object graph stored in the checkpoint is reconstructed, including malicious callables embedded by an attacker.
Attack Vector
Exploitation requires a user to load an attacker-supplied checkpoint, which aligns with the User Interaction requirement in the CVSS vector. Common delivery channels include compromised or typosquatted model repositories, malicious pull requests adding pretrained weights, shared research artifacts, and supply-chain tampering of model registries. Once load_from_checkpoint() is called on the malicious .ckpt file, code execution occurs in the context of the data science workstation, training cluster, or inference service that performed the load. There are no public proof-of-concept exploits referenced in the advisory.
The vulnerability mechanism mirrors prior pickle-based attacks against ML serialization formats: a crafted object overrides __reduce__ to return a tuple invoking os.system, subprocess.Popen, or another Python callable during deserialization. See the GitHub PyTorch Lightning Repository for the checkpoint loading implementation.
Detection Methods for CVE-2026-31221
Indicators of Compromise
- Unexpected child processes spawned by Python interpreters that recently invoked torch.load() or load_from_checkpoint().
- Outbound network connections from training or inference hosts immediately after checkpoint loads.
- .ckpt or .pt files originating from untrusted sources, public mirrors, or unsigned model registries.
- New persistence artifacts (cron entries, systemd units, shell profile modifications) on ML workstations after model downloads.
Detection Strategies
- Inspect checkpoint files with pickletools or fickling to flag unsafe opcodes such as GLOBAL, REDUCE, or references to os, subprocess, builtins.eval, and builtins.exec.
- Hunt for Python processes executing shell binaries (sh, bash, cmd.exe, powershell.exe) as direct children of training jobs.
- Audit code repositories for calls to LightningModule.load_from_checkpoint() and torch.load() that omit weights_only=True.
Monitoring Recommendations
- Forward endpoint process telemetry from ML workstations and GPU servers into a centralized data lake for behavioral analysis.
- Alert on Python processes that load checkpoint files and subsequently establish outbound network sessions or modify filesystem locations outside the project directory.
- Track downloads of .ckpt, .pt, and .pth artifacts from non-allowlisted hosts.
How to Mitigate CVE-2026-31221
Immediate Actions Required
- Upgrade PyTorch-Lightning to a version later than 2.6.0 that enforces weights_only=True when one becomes available from the maintainers.
- Treat all externally sourced checkpoints as untrusted and load them only inside sandboxed, network-restricted environments.
- Replace pickle-based checkpoint distribution with safetensors where the workflow permits.
- Inventory and review every code path that calls load_from_checkpoint() or torch.load() on third-party files.
Patch Information
No vendor advisory or fixed version is listed in the NVD record at publication time. Monitor the GitHub PyTorch Lightning Repository for an official patch and release notes. Until a fix is published, apply the workarounds below.
Workarounds
- Pass weights_only=True explicitly to torch.load() and avoid LightningModule.load_from_checkpoint() for untrusted files.
- Verify checkpoint integrity with cryptographic signatures or hash allowlists before loading.
- Run model loading in isolated containers with no network egress and minimal filesystem privileges.
- Pre-scan checkpoints with tools such as fickling or picklescan in CI pipelines before promotion.
# Configuration example: safer manual checkpoint load
python - <<'EOF'
import torch
# Restrict deserialization to tensor data and safe types
state = torch.load("model.ckpt", weights_only=True, map_location="cpu")
print(list(state.keys()))
EOF
# Pre-flight scan untrusted checkpoints in CI
pip install fickling
fickling --check-safety model.ckpt
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


