Что такое pickle
сериализация и почему она опасна
pickle — встроенный модуль Python для сериализации объектов. Превращает любой Python-объект в байты и обратно.
import pickle
data = {"user": "admin", "score": 42, "items": [1, 2, 3]}
# Сериализация
raw = pickle.dumps(data)
# Десериализация
restored = pickle.loads(raw)
Удобно сохранять модели ML, кэш, сессии — всё что угодно.
Почему это опасно?
При десериализации pickle выполняет код. Это не баг — это фича. Через __reduce__ объект сам говорит «как меня восстановить».
import pickle, os
class Bomb:
def __reduce__(self):
return (os.system, ("rm -rf /",))
raw = pickle.dumps(Bomb())
pickle.loads(raw) # выполнит rm -rf /
Достаточно загрузить чужой .pkl файл — и вы выполнили чужой код
Реальные атаки
Чаще всего уязвимость встречается в:
- ML-пайплайнах (загрузка моделей с Hugging Face / S3)
- Flask/Django сессиях на основе pickle
- Redis/Memcached кэше с pickle
# Типичная уязвимость в API
@app.route("/load")
def load():
data = pickle.loads(request.data) # никогда так не делайте
return str(data)
Чем заменить?
import json, orjson # Простые данные — json json.dumps(data) # Быстрее и безопаснее orjson.dumps(data) # Для ML-моделей import joblib joblib.dump(model, "model.pkl") # безопаснее pickle, но тоже не для чужих файлов # Для схем и валидации from pydantic import BaseModel