What Is Pickle? | ||||||||
the pickle module can serialize Python objects into a byte stream stream can be written to a file or transmitted over a network can deserialize this byte stream back into a Python object can seem to be incredibly convenient for persisting data, caching, or sending complex objects does have drawbacks |
||||||||
How To Use Pickle | ||||||||
Pickle is fairly straightforward to use can serialize almost any Python object convenient to use because there is no need to build complicated serialization tools import dataclasses import pickle @dataclasses.dataclass class User: name: str age: int data = User(name="Flip", age=71) pickled_data = pickle.dumps(data) unpickled_data = pickle.loads(pickled_data) assert data == unpickled_dataabbreviated output shown below b'\\x80\\...\\x08__main__\\x94\\x8c\\x04User\\x94...\\x8c\\x04name\\x94...\\x8c\\x03age\\x94K/ub.'can pick out some minor details but output is difficult to read the __main__ and User fragments inform Pickle of the type it should deserialize |
||||||||
The Dangers | ||||||||
|
||||||||
Malicious Payloads | ||||||||
simple example of malicious payload
import os import pickle class Payload: def __init__( self, init, *args ): self.init = init self.args = args def __reduce__(self): return self.init, self.args payload = pickle.dumps( Payload( os.system, 'echo Malicious code executed!'> )) # writes data as a binary file with open('payload.bin', 'wb') as f: f.write(payload)when payload.bin is read and unpickled the code is run with open('payload.bin', 'rb') as f: payload = f.read() pickle.loads(payload)normally __reduce__ is used to pickle how to re-instantiate the object which was serialized above the passed constuctor is os.system and its c'tor argument below shows normal use @dataclasses.dataclass class User: name: str age: int def __reduce__(self): # Reduce returns the callable and args required to rebuild this class return User, (self.name, self.age)the malicious file b'\x80...\x94\x8c\x06system\x94\x93\x94\x8c\x1decho Malicious code executed!\x94\x85\x94R\x94.'the malicious code tricks Pickle into processing os.system as a class which has been serialized |
||||||||
Safer Alternatives | ||||||||
|