A pickle file is a binary file made by Python's pickle module to save and restore objects. Reading one executes a sequence of instructions, and some can import modules and call functions. That is why loading a pickle from a source you do not trust can run attacker code.
Why pickle is everywhere in ML
Pickle handles almost any Python object with no extra work. That convenience made it the default for saving models, scalers, tokenizers and preprocessing pipelines. Hugging Face notes that pickle is the default format for PyTorch model weights, so a large share of public model files are pickles or contain one.
How a pickle becomes a program
Hugging Face's documentation describes a pickle as a stack of instructions, read one by one when the file is loaded. Three of those instructions matter for security: GLOBAL and STACK_GLOBAL, which import something, and REDUCE, which calls it with arguments.
According to that documentation, this combination lets a file import built-in functions such as eval or exec and run them. A constructor can also run when an object is rebuilt. The Python docs say it plainly: it is possible to construct malicious pickle data which will execute arbitrary code during unpickling.
You can read a pickle without running it
The standard library includes pickletools, which can disassemble a pickle without executing it. Hugging Face uses the same idea on the Hub to list the imports a pickled file references.
import pickletools
with open("model.pkl", "rb") as f:
pickletools.dis(f)
In the output, look at lines that import modules. A file that references os, subprocess, builtins or similar is worth a close look before anyone loads it. This is a manual check, and Hugging Face states that its own import scan is not 100 percent foolproof, so treat it as one signal.
Ways to reduce the risk
- Prefer another format. Python's docs suggest safer formats such as json for untrusted data. For model weights, safetensors is the common alternative.
- Restrict what can be imported. Python lets you subclass Unpickler and override find_class so only an allow list of names is accepted.
- Check where the file came from. A signed commit from a publisher you know tells you who made the file. It does not tell you the file is safe.
- Detect tampering. The Python docs suggest signing data with hmac if you need to know it was not changed.
- Load in isolation. If you must open an unknown pickle, do it somewhere with no credentials and no network.
What this means for your inventory
Pickles are artifacts, not packages, so a normal dependency list will miss them. Add model files and serialized preprocessors to your inventory, with their source and hash. Our guide to model supply chain attacks covers the wider threat.
Where Safeguard fits
Safeguard handles the package side: SBOM generation, dependency scanning and reachability for the libraries around your models. A free scan is available at gold.safeguard.sh/scan.
Quick check
Is every pickle file malicious?
No. Most are harmless. The issue is that you cannot tell from the extension, and the format allows code to run on load, so the source matters.
Can I just scan the file with antivirus?
Not reliably. Hugging Face says that ClamAV covers a good amount of dangerous files but does not cover pickle exploits, which is why it added a separate import scan.
Sources
Last reviewed: 19 October 2026.