criticalCode Injection

Insecure Deserialization of User Input

What Is This Vulnerability?

Insecure deserialization occurs when an application deserializes data from an untrusted source without validation. Attackers can craft malicious serialized objects that, when deserialized, execute arbitrary code, tamper with application logic, or escalate privileges. This is especially dangerous in languages and frameworks that support complex object serialization.

Why It Happens

Applications serialize objects for session management, caching, inter-process communication, or API payloads. When the serialized format allows embedding executable code or class instantiation instructions (as in Python pickle, Java ObjectInputStream, or PHP unserialize), deserializing untrusted data can trigger code execution during the reconstruction process.

Example Code

Vulnerableapp.py
import pickle
import base64
from flask import Flask, request

app = Flask(__name__)

@app.route("/load-session", methods=["POST"])
def load_session():
    data = base64.b64decode(request.form["session"])
    session = pickle.loads(data)
    return f"Welcome back, {session['username']}"
Fixedapp.py
import json
import hmac
import hashlib
from flask import Flask, request

app = Flask(__name__)
SECRET = os.environ["SESSION_SECRET"]

@app.route("/load-session", methods=["POST"])
def load_session():
    payload = request.form["session"]
    signature = request.form["signature"]
    expected = hmac.new(SECRET.encode(), payload.encode(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(signature, expected):
        return "Invalid session", 403
    session = json.loads(payload)
    return f"Welcome back, {session['username']}"

How Hackers Exploit It

Attackers craft a serialized payload that instantiates dangerous classes during deserialization. In Python, a pickle payload can execute os.system() to run shell commands. In Java, gadget chains in common libraries allow remote code execution through crafted ObjectInputStream data. The attacker simply sends this payload wherever the application accepts serialized input.

How to Fix It

Avoid deserializing untrusted data with formats that support code execution (pickle, Java serialization, PHP unserialize). Use safe data formats like JSON for untrusted input. If you must use complex serialization, sign the data with HMAC and verify the signature before deserializing. Implement allowlists for permitted classes and restrict deserialization to known safe types.

Frequently Asked Questions

Why is pickle dangerous for untrusted data?
Python's pickle module can serialize and deserialize arbitrary Python objects, including those that execute code during reconstruction. An attacker can craft a pickle payload that calls os.system() or subprocess.Popen() when deserialized, giving them shell access.
Is JSON safe from deserialization attacks?
JSON itself only supports primitive types (strings, numbers, booleans, arrays, objects), so it cannot directly trigger code execution during parsing. However, if the application processes JSON values unsafely after parsing (for example, passing values to eval()), vulnerabilities can still arise.
How does HMAC signing prevent deserialization attacks?
HMAC signing creates a cryptographic signature of the serialized data using a secret key. Before deserializing, the application verifies the signature matches. Since the attacker does not know the secret key, they cannot forge a valid signature for their malicious payload.

Related Security Topics

Check Your Code for This Vulnerability

Run a free scan to check if your site is affected by insecure deserialization of user input.