все Python 3pickleпонятие
pickle.Unpickler
загрузка
Класс, читающий объекты pickle из двоичного файла. Переопределив find_class(), можно разрешить загрузку только безопасных типов.
Синтаксис
u = pickle.Unpickler(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)
pickle.load() — это Unpickler(file).load(). Главная причина завести свой класс — безопасность: при загрузке pickle по имени из потока импортирует любой модуль и вызывает любую функцию, например os.system, поэтому недоверенные данные исполняют чужой код. find_class(module, name) вызывается на каждое такое имя: разрешите в нём короткий белый список, остальное отклоняйте UnpicklingError. Это сужает атаку, но не делает pickle форматом обмена: для данных из сети и от пользователей — json.
Примеры
import io, pickle
class Safe(pickle.Unpickler):
def find_class(self, module, name):
if module == 'builtins' and name in {'set', 'frozenset'}:
return super().find_class(module, name)
raise pickle.UnpicklingError(f'запрещено: {module}.{name}')
class Evil:
def __reduce__(self):
return (print, ('взлом!',))
try:
Safe(io.BytesIO(pickle.dumps(Evil()))).load()
except pickle.UnpicklingError as e:
print(e) # → запрещено: builtins.print
print(Safe(io.BytesIO(pickle.dumps(['ok', 1]))).load()) # → ['ok', 1]
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности