Frontier AI Security: Attack Surfaces · 2 of 5
Unsafe Deserialization: Pickle vs Safetensors
Some AI model files can run code when loaded; safetensors removes that class of risk by storing only tensors, not executable instructions.
One of the least intuitive facts in artificial intelligence (AI) security is that loading a model file can execute code before the model is ever used. The danger is not that the model gives a bad answer. The danger is earlier and quieter: the file format itself may let the file tell the loader what code to run while rebuilding objects in memory. That is why a downloaded model should be treated less like a photograph and more like software, unless its format is designed to contain data only.
The surprising part is the word loading
Most people draw a clean line between opening data and running a program. That line is useful, but it is not always real. Some file formats are passive containers: they describe values, shapes, and bytes. Other formats are active recipes: they describe how to recreate a live object, and the recipe can include calls into code.
AI systems often load large model files from shared repositories, internal artifact stores, research checkpoints, evaluation bundles, and vendor drops. That makes model loading a supply-chain event. If the format can carry executable behavior, the act of loading becomes a trust decision.
Unsafe deserialization is the name for this class of problem. Serialization writes an in-memory object to bytes. Deserialization reads those bytes and rebuilds the object. The risk appears when the rebuilding process gives the file enough power to invoke code.
Serialization turns objects into bytes, and back again
A trained model is not stored on disk as a living thing. In memory, it has tensors, layer names, configuration objects, optimizer state, and sometimes custom classes. To save it, software must flatten that state into a stream of bytes. That is serialization.
Later, a loader reverses the process. It reads the bytes, allocates memory, creates objects, fills tensors, and reconnects structure. That is deserialization. This is a trust boundary because the loader is taking instructions from a file and turning them into live state inside a process.
The central security question is simple: does the format allow the file to describe only data, or does it also allow the file to describe behavior?
Why pickle is powerful, and why that power is dangerous
Pickle is Python’s general-purpose object serialization format. Python is a widely used programming language in machine learning, and pickle became common because it is convenient: it can represent many Python objects, not just arrays of numbers.
That convenience is the issue. Pickle is not merely a data format. A pickle stream can contain instructions for reconstructing objects, including references to functions and classes that the loader should import and call. This is not an accidental bug in pickle; it is part of how pickle supports rich Python objects.
If the pickle file is malicious, those reconstruction steps can be chosen to execute attacker-controlled behavior. In practical terms, loading an untrusted pickle is similar to running untrusted code with the permissions of the loading process.
This matters for model files because many historical checkpoints and framework-specific files have used pickle or pickle-like mechanisms. File extensions alone are not a reliable safety signal; a file named like a model checkpoint may still trigger pickle deserialization underneath.
Why safetensors changes the shape of the problem
Safetensors was designed for a narrower job: storing tensors safely and efficiently. A tensor is a multidimensional array of numbers, and model weights are tensors learned during training. The format records information such as tensor names, data types, shapes, and the raw bytes for the tensor values.
The important security property is what safetensors leaves out. It does not provide a mechanism for arbitrary Python object reconstruction. It does not tell the loader to import a class, call a function, or run a method. A safetensors loader reads metadata and tensor bytes, then returns tensors.
This is a structural defense. It does not depend on guessing whether a file is malicious. It removes the feature that would let the file carry code in the first place. A parser could still have an ordinary software bug, as any parser can, but the format does not intentionally expose code execution as part of loading.
What safe loading looks like in practice
The safest default is boring: prefer non-executing formats for model weights, and treat code-capable formats as untrusted software. This is especially important in evaluations, automated testing, model comparison pipelines, and research environments where many artifacts are downloaded and loaded quickly.
When safetensors is available, use it for weights. When a workflow requires pickle, isolate the loading step as if it were hostile. Isolation means the process has minimal privileges, no unnecessary secrets, tightly controlled file-system access, and no default network egress. The goal is to limit what a malicious file can reach if it executes.
Safer loading modes in machine-learning frameworks can reduce risk, especially when they restrict loading to weights rather than arbitrary objects. They are useful controls. They do not change the basic rule: arbitrary pickle from an untrusted source should not be deserialized in a trusted process.
- Prefer safetensors or another data-only format for model weights.
- Do not load untrusted pickle files on a developer laptop or production host.
- Run unavoidable pickle loading in a sandbox with least privilege.
- Remove secrets and cloud credentials from the loading environment.
- Block network egress unless the load step has a specific approved need.
- Record the source, hash, and format of every model artifact you load.
The real decision is a policy decision
For leaders and practitioners, this is not only a library choice. It is a policy about what kinds of artifacts your organization accepts, who may introduce them, and where they may be loaded. A team that says “we scan models” is making a different bet from a team that says “we do not accept executable model formats unless isolated.”
The practical question is not whether pickle is useful. It is useful. The question is where its power is allowed. In a trusted development workflow with known authors and controlled code, pickle may be an accepted engineering tradeoff. In a public model intake path, benchmark evaluation, continuous integration job, or production deployment pipeline, the same choice can become an unnecessary exposure.
Good policy is specific enough to automate. Artifact registries can label formats. Continuous integration can fail builds that introduce disallowed formats. Evaluation harnesses can require safetensors for downloaded weights. Exceptions can be routed through sandboxed loaders and reviewed like other software supply-chain exceptions.
What safetensors does not solve
Safetensors closes the unsafe deserialization door for model weights, but it does not make the whole AI supply chain safe by itself. A model repository may also contain Python code, configuration files, tokenizer files, dataset loaders, install scripts, notebooks, or evaluation harnesses. Those may still execute code through normal program behavior.
A safe tensor file can also contain a harmful model in a different sense: a model may be backdoored, biased, stolen, poisoned, or unsuitable for the task. Safetensors prevents code execution through the weight file format; it does not prove that the model is trustworthy, licensed correctly, or behaviorally safe.
That distinction is important. Use safetensors because it removes one avoidable class of technical risk. Then continue with the rest of the discipline: provenance, sandboxing, dependency control, network restrictions, secrets hygiene, and careful evaluation.
Key takeaways
- Deserialization is a trust boundary because a file is being turned into live state inside a running process.
- Pickle can store object-reconstruction instructions, and those instructions can execute code during loading.
- Safetensors stores tensor data and metadata, not arbitrary executable reconstruction logic.
- Prefer data-only formats for model weights, especially for public, automated, or high-scale model intake.
- If pickle cannot be avoided, load it only in a strongly isolated environment with minimal privileges, no secrets, and controlled network access.
- Safetensors reduces one major attack surface, but it does not replace broader AI supply-chain security.
Glossary
- Serialization
- The process of writing an in-memory object or data structure into bytes that can be stored or transmitted.
- Deserialization
- The process of reading stored bytes and rebuilding live objects or data structures in memory.
- Unsafe deserialization
- A vulnerability class in which loading a file can cause unintended or attacker-controlled code to run.
- Pickle
- Python’s general-purpose serialization format, which can reconstruct complex objects and may execute code during loading.
- Safetensors
- A model-weight file format designed to store tensors and metadata without an executable object-reconstruction mechanism.
- Tensor
- A multidimensional array of numbers used to represent model weights, activations, and other machine-learning data.
- Model weights
- The learned numerical parameters of a model, usually stored as tensors.
- Sandbox
- An isolated execution environment that limits what a process can access if it behaves maliciously or unexpectedly.
- Structural defense
- A security control that removes the possibility of a class of attack rather than trying to detect each instance of it.