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
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']}"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.