flawopen.com/Insecure Deserialization/Python pickle

Is Python's pickle.load() safe on untrusted data?

Reference page — draft, pending review
ELI5

No — and this isn't a subtle edge case. Python's own documentation states plainly that unpickling data from an untrusted source can execute arbitrary code, by design. Pickle isn't a data format like JSON — it's closer to a small program describing how to reconstruct an object, and that reconstruction process can be made to run arbitrary code.

DANGEROUS
# data from a network request, a cache,
# a cookie, a file upload — all untrusted
obj = pickle.loads(untrusted_bytes)
SAFER ALTERNATIVE
# use a data-only format instead
obj = json.loads(untrusted_bytes)

Why pickle is fundamentally different from JSON

Pickle's format can encode instructions to call arbitrary callables during reconstruction — a maliciously crafted pickle stream can be built to invoke something like os.system() the moment it's unpickled, with no separate "execute" step required. This isn't a bug to patch; it's how the format is designed to work, which is why the fix is "don't unpickle untrusted data," not "unpickle it more carefully."

FAQ

Is there a safe way to use pickle with untrusted data?

Restricting unpicklers (e.g., overriding find_class to allow-list specific types) is possible but genuinely hard to get completely right — for untrusted data, switching to a data-only format (JSON, or a schema-validated format) is the far more reliable default.

Is this specific to pickle, or does it apply elsewhere?

The pattern — deserialization that can trigger code execution — exists in other languages too, notably Java's native serialization and PHP's unserialize(). It's a recurring shape across ecosystems, not a Python-only quirk.

References