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