Python Pickle 模块
What pickle can store, why it is unsafe, and when to use JSON instead.
Key PointsUnpickling arbitrary data executes code — never load a pickle you did not create; use JSON for anything crossing a trust boundary.
Round Trip
pickle stores almost any Python object — custom instances, datetime, numpy arrays. That is its only advantage over JSON.
Python
import pickle
from datetime import datetime
data = {"when": datetime(2026, 10, 31), "nums": [1, 2, 3]}
blob = pickle.dumps(data)
print(len(blob) > 0, blob[:2])
back = pickle.loads(blob)
print(back["when"].year)Output
True b'\x80\x04'
2026Files and Protocol
Python
import pickle
with open("cache.pkl", "wb") as f:
pickle.dump({"a": 1}, f, protocol=pickle.HIGHEST_PROTOCOL)
with open("cache.pkl", "rb") as f:
print(pickle.load(f))Output
{'a': 1}Why It Is Dangerous
pickle.loads follows instructions in the byte stream to import modules and call functions — an attacker can craft a payload that runs os.system on load. It is equivalent to eval.
| Use case | Choose |
|---|---|
| Local cache you wrote yourself | pickle (fast, any object) |
| HTTP API payload | JSON |
| Config file | JSON / TOML / YAML |
| Cross-language data | JSON / MessagePack |
| Untrusted input | Never pickle |
Store JSON or msgpack in Redis/queues, never pickle — a writable queue becomes remote code execution.
序列化与还原
pickle 能存几乎任何 Python 对象:自定义类实例、datetime、numpy 数组。这是它相对 JSON 的唯一优势。
Python
import pickle
from datetime import datetime
data = {"when": datetime(2026, 10, 31), "nums": [1, 2, 3]}
blob = pickle.dumps(data)
print(len(blob) > 0, blob[:2])
back = pickle.loads(blob)
print(back["when"].year)Output
True b'\x80\x04'
2026文件与协议版本
Python
import pickle
with open("cache.pkl", "wb") as f:
pickle.dump({"a": 1}, f, protocol=pickle.HIGHEST_PROTOCOL)
with open("cache.pkl", "rb") as f:
print(pickle.load(f))Output
{'a': 1}为什么危险
pickle.loads 会按字节流里的指令去 import 模块并调用函数,攻击者可以构造一个在加载时执行 os.system 的对象。它等价于 eval。
| 场景 | 选择 |
|---|---|
| 自己写的本地缓存 | pickle(快,支持任意对象) |
| HTTP 接口数据 | JSON |
| 配置文件 | JSON / TOML / YAML |
| 跨语言数据 | JSON / MessagePack |
| 不可信输入 | 绝不用 pickle |
Redis / 消息队列里存对象时,用 JSON 或 msgpack,不要 pickle —— 队列一旦被别人写入,就等于远程代码执行。