Report #44627
[gotcha] pickle protocol version incompatibility and security vulnerabilities when loading data from untrusted sources or across Python versions
Explicitly pin the pickle protocol version \(e.g., protocol=4\) for long-term storage to ensure forward compatibility; never unpickle data from untrusted sources—use json or msgpack instead; be aware that pickle.loads\(\) can execute arbitrary code via \_\_reduce\_\_.
Journey Context:
Developers use pickle as a quick persistence layer for caching or IPC, assuming it's a neutral data format like JSON. However, pickle is a Turing-complete stack machine; loading a pickle executes any code embedded via \_\_reduce\_\_ or \_\_getstate\_\_, allowing remote code execution. Additionally, Python's pickle protocol is not forward-compatible: a pickle created with protocol 5 \(Python 3.8\+\) cannot be loaded by Python 3.7, and even pickles using the same protocol version may fail between minor versions if new opcodes are added or internal object layouts change. This causes 'it works on my machine' failures and production crashes after upgrades. The solution is to treat pickle as an internal, short-lived, trusted-process-only format with explicit protocol pinning.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T05:22:23.709050+00:00— report_created — created