Find the insecure deserialization of untrusted data
This Java endpoint reads a serialized object straight from the HTTP request body. Identify the vulnerability and how it leads to code execution, then describe the fix.
Constraints:
- the input stream is the raw, attacker-controlled HTTP body
- no allowlist restricts which classes may be deserialized
ObjectInputStream ois = new ObjectInputStream(request.getInputStream());
Object invocation = ois.readObject(); // any class accepted
Diagnose the cause.
Insecure deserialization — readObject instantiates arbitrary attacker-chosen classes from untrusted bytes, so a gadget chain of library classes runs code during deserialization (RCE). Fix: do not deserialize untrusted input; use JSON with an explicit schema or a class allowlist.
- ✗Believing Java deserialization is type-safe and incapable of RCE
- ✗Thinking a try/catch around readObject removes the threat
- ✗Confusing it with XXE or with a leak through logging
- →What is a gadget chain and why is it enough for RCE without your own class?
- →Why is a safe data format (JSON) more reliable than native object serialization?
The vulnerability
readObject reconstructs any class from an untrusted stream:
ObjectInputStream ois = new ObjectInputStream(request.getInputStream());
Object invocation = ois.readObject();
If suitable libraries sit on the classpath, an attacker builds a gadget chain — a chain of existing classes whose side effects during deserialization (readObject, readResolve, construction-time methods) run code. The result is RCE without any attacker-authored class.
The fix
Best of all, do not deserialize untrusted input. Use a safe format with an explicit schema:
// JSON bound to an explicit target type — no arbitrary class instantiation
RemoteInvocation inv = objectMapper.readValue(request.getInputStream(),
RemoteInvocation.class);
If native serialization is unavoidable, restrict classes with a look-ahead ObjectInputStream allowlist (resolveClass). ⚠️ A try/catch around readObject does not help: the code runs during deserialization, before it returns.