Python Insecure Deserialization
What is Python Insecure Deserialization?
What are the risks of Python Insecure Deserialization?
Even if the application validates deserialized data afterward, the attack may already have been executed. This can lead to full system compromise, unauthorized data access, or an application crash.
A common exploit scenario involves sending a malicious serialized object to an application that blindly deserializes it. If the object contains instructions to execute system commands, it can result in full system compromise.
How to fix (and prevent) Python Insecure Deserialization?
The best approach is to avoid using pickle for untrusted data. Instead, use safer formats like JSON, which only supports basic data types and does not allow arbitrary code execution.
If serialization cannot be avoided, implement cryptographic signing to ensure the integrity of serialized objects. Additionally, restricting deserialization functionality and implementing strict input validation can help prevent attacks.
import pickle
import hmac
import hashlib
import base64
import os
# secret key for signing (store securely, e.g., in an environment variable)
SECRET_KEY = os.environ.get("SERIALIZATION_SECRET_KEY", "supersecretkey").encode()
def sign_data(data: bytes, key: bytes) -> str:
"""Generate an HMAC signature for the given data."""
return hmac.new(key, data, hashlib.sha256).hexdigest()
def secure_serialize(obj) -> str:
"""Serialize an object securely by signing it with HMAC."""
serialized_data = pickle.dumps(obj)
signature = sign_data(serialized_data, SECRET_KEY)
# Encode serialized data in base64 for safe storage or transmission
encoded_data = base64.b64encode(serialized_data).decode()
return f"{signature}:{encoded_data}"
def secure_deserialize(signed_data: str):
"""Deserialize an object securely after verifying its signature."""
try:
signature, encoded_data = signed_data.split(":", 1)
serialized_data = base64.b64decode(encoded_data)
# Verify signature
expected_signature = sign_data(serialized_data, SECRET_KEY)
if not hmac.compare_digest(expected_signature, signature):
raise ValueError("Tampered data detected! Signature mismatch.")
return pickle.loads(serialized_data)
except (ValueError, pickle.UnpicklingError, IndexError) as e:
raise ValueError(f"Deserialization error: {e}") from e
# Example usage
if __name__ == "__main__":
# Sample object to serialize
data = {"username": "admin", "role": "superuser"}
# Securely serialize
signed_data = secure_serialize(data)
print("Serialized & Signed Data:", signed_data)
# Securely deserialize
try:
deserialized_data = secure_deserialize(signed_data)
print("Deserialized Data:", deserialized_data)
except ValueError as e:
print("Error:", e)
This Python script securely serializes and deserializes objects using HMAC signing. The secure_serialize
function signs the serialized object with HMAC-SHA256, ensuring integrity. The secure_deserialize
function verifies the signature before loading the object, preventing tampering. If an attacker modifies the serialized data, the signature check fails, protecting against insecure deserialization attacks.
Note: These scripts are for educational purposes only. Always ensure you have permission before scanning or testing websites you don't own or operate.
Vulnissimo scored the severity risk of this vulnerability to 85 out of 100. This means that it requires immediate attention.
Vulnissimo tests for Python Insecure Deserialization and many more. Sharpen your security posture with our advanced web vulnerability scanner.