Pickle Internals, Fickling & ModelScan Usage for ML Artifact Security
Written by Aryan Giri
1. Introduction
Python serialization is convenient, but it becomes dangerous the moment untrusted model files enter the workflow. pickle can carry execution behavior during deserialization, which is why pickle-based ML artifacts are a classic supply-chain risk.
This article covers:
pickletoolsfor disassembling pickle bytecodeFicklingfor decompiling and analyzing pickle filesh5py/ HDF5 as a second model-file surfaceModelScanfor scanning model artifacts before loading them
2. What Pickling Does
Pickling converts Python objects into a byte stream. Unpickling restores them later.
import pickle
obj = {"user": "aryan", "role": "analyst"}
blob = pickle.dumps(obj)
restored = pickle.loads(blob)
print(restored)
The risk is simple: loading a malicious pickle can trigger code execution during deserialization.
3. Why Pickle is Dangerous
pickle is not just data storage. It can reference functions and reconstruct objects through execution-like behavior.
Common abuse paths include:
__reduce__abuse- malicious opcode chains
- hidden imports
- payloads embedded in model files
import pickle
import os
class Evil:
def __reduce__(self):
return (os.system, ("whoami",))
payload = pickle.dumps(Evil())
# Never load untrusted pickle data.
4. pickletools: Disassemble the Bytecode
pickletools is the first lens for inspecting a suspicious pickle file. It disassembles pickle bytecode without executing it.
CLI usage
python -m pickletools model.pkl
Useful examples
python -m pickletools suspicious.pkl > disassembly.txt
python -m pickletools model.pkl | less
Why it matters
It lets you inspect opcodes such as GLOBAL, REDUCE, and BUILD so you can understand how the object will be reconstructed.
5. Fickling: Decompiler and Static Analyzer
Fickling goes deeper than raw opcode dumps. It is a decompiler, static analyzer, and bytecode rewriter for Python pickle serializations.
Install
python -m pip install fickling
CLI examples
fickling --help
fickling --trace model.pkl
fickling --check-safety -p model.pkl
What it is good for
- tracing pickle execution safely
- checking whether a file looks malicious
- decompiling pickle logic into a more readable form
Programmatic check example
import fickling
if not fickling.is_likely_safe("model.pkl"):
print("Unsafe file")
6. h5py and HDF5: The Other Model Format You Should Know
The common Python library for HDF5 is h5py. It is a Pythonic interface to the HDF5 binary data format.
Install
python -m pip install h5py
Tiny example
import h5py
with h5py.File("model.h5", "r") as f:
print(list(f.keys()))
HDF5 files are common in ML workflows, so they belong in any model-file review workflow.
7. ModelScan: Scan the Artifact Before Loading It
ModelScan is built to scan model files for unsafe code patterns across multiple formats, including Pickle and H5.
Install
python -m pip install modelscan
Basic scan
modelscan -p model.pkl
More examples
modelscan -p suspicious.pkl
modelscan -p model.h5
modelscan -h
modelscan -v
Create a settings file
modelscan create-settings-file
Why it matters
It gives you a fast static scan before a model ever reaches pickle.load(), torch.load(), or similar loaders.
8. A Practical Triage Flow
- Identify the file type.
- Run
pickletoolsif it is a pickle artifact. - Run
Ficklingfor deeper inspection. - Run
ModelScanacross the file. - Only then decide whether the artifact is safe to load in a sandbox.
Example triage session
file model.pkl
python -m pickletools model.pkl > disassembly.txt
fickling --check-safety -p model.pkl
modelscan -p model.pkl
9. Key Takeaways
pickletoolshelps you inspect pickle bytecode safely.Ficklingadds decompilation, tracing, and safety checks.h5pymatters because HDF5 model files are also a real attack surface.ModelScangives you a fast static scan across model formats.