Safeguard
AI Security•

What is a pickle file, and why do ML teams worry about it?

A pickle file is Python's object serialization format, and loading one can run code. Here is how it works, why ML uses it, and how to reduce the risk.

Safeguard Security Team
3 min read

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

  1. Prefer another format. Python's docs suggest safer formats such as json for untrusted data. For model weights, safetensors is the common alternative.
  2. Restrict what can be imported. Python lets you subclass Unpickler and override find_class so only an allow list of names is accepted.
  3. 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.
  4. Detect tampering. The Python docs suggest signing data with hmac if you need to know it was not changed.
  5. 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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.