Python Glossary English

все 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Сообщить о неточности