Python Insecure Deserialization

high Severity
Detected By: active Mode

What is Python Insecure Deserialization?

Python insecure deserialization occurs when an application deserializes untrusted data, allowing attackers to inject malicious payloads into the deserialization process. Since Python's pickle and marshal modules can execute arbitrary code during deserialization, this vulnerability can lead to Remote Code Execution (RCE), data breaches, and Denial of Service (DoS).

What are the risks of Python Insecure Deserialization?

If an attacker manipulates serialized data (e.g., pickled objects) and sends it to a vulnerable application, the deserialization process may execute unintended code. Python's pickle module can store not just data but also executable code, allowing attackers to craft payloads that run arbitrary commands.

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.

Severity Level
high
85%

Vulnissimo scored the severity risk of this vulnerability to 85 out of 100. This means that it requires immediate attention.

Test Your Application for Python Insecure Deserialization Now

Vulnissimo tests for Python Insecure Deserialization and many more. Sharpen your security posture with our advanced web vulnerability scanner.