Python Glossary Русский

all Python 3pickleterm

pickle.Unpickler

deserialization

A class that reads pickled objects from a binary file. Overriding find_class() lets you allow only safe types to be loaded.

Syntax

u = pickle.Unpickler(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)

pickle.load() is Unpickler(file).load(). The main reason for your own subclass is security: while loading, pickle imports any module and calls any function named in the stream, os.system for instance, so untrusted data executes someone else's code. find_class(module, name) is called for every such name: allow a short whitelist there and reject the rest with UnpicklingError. This narrows the attack but does not make pickle an exchange format: for data from the network or users use json.

Examples

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]

See also

Open in the full glossarydocs.python.orgReport an inaccuracy