flawopen.com/Java deserialization/ObjectInputStream safety
Is Java ObjectInputStream safe for untrusted data?
Usually, no: readObject() rebuilds a graph of Java objects and may run class-defined deserialization methods while doing so. Think of it like accepting a flat form but letting every included component bring its own setup instructions; a hostile stream can reach behavior in classes already available to the application. That does not mean every call causes code execution: reachability depends on the accepted classes, libraries, code paths, and input boundary.
// Do not pass attacker-controlled bytes here.
try (var in = new ObjectInputStream(untrustedStream)) {
Object value = in.readObject();
handle(value);
}
// Keep polymorphic/default typing disabled for untrusted input.
ObjectMapper mapper = new ObjectMapper();
OrderRequest value = mapper.readValue(
untrustedBytes, OrderRequest.class
);
validate(value);
How a deserialization flaw becomes reachable
A network handler, message broker, cache, or file import accepts attacker-influenced serialized bytes. If those bytes reach ObjectInputStream.readObject(), the JVM reconstructs objects using serializable classes present in the process. A gadget chain is a possible path through existing class behavior; it is not a special payload built into every Java stream. Exploitation depends on the exact classes, reachable methods, application context, and any filtering. Oracle documented one product-specific case in CVE-2015-4852: unauthenticated network attacks via WebLogic T3 against listed WebLogic versions. That advisory does not mean every ObjectInputStream use is remotely reachable.
If native serialization cannot be removed
- ✓Prefer a data-only format with an explicit schema, such as JSON or Protocol Buffers; map it into a fixed DTO and validate fields and authorization after parsing.
- ✓If native serialization is unavoidable, install a context-specific
ObjectInputFilterbeforereadObject(); allow only the exact classes required for that stream and reject everything else. - ✓Set filter limits for depth, references, array length, and stream bytes based on measured valid inputs. A class allow-list alone does not prevent resource exhaustion.
- ✓Do not enable broad polymorphic/default typing for untrusted JSON. A data-only parser can become object construction again when arbitrary subtype metadata is accepted.
- ✓Keep Java and dependencies patched, remove unused serializable libraries, and process legacy streams with least privilege and bounded resource access.
Frequently asked question
It reduces risk when configured before deserialization with a narrow, context-specific class allow-list and resource limits. It is not a universal sanitizer: the allowed classes and their deserialization behavior still matter, filter configuration must actually be active, and application-level validation and authorization remain necessary. Avoid native serialization for attacker-controlled data whenever practical.
Primary sources
- Oracle Secure Coding Guidelines for Java SE — Serialization and Deserialization
- Oracle Java Serialization Filters (JDK 25)
- Oracle Security Alert — CVE-2015-4852
- OWASP Deserialization Cheat Sheet
- Jackson Databind — Polymorphic Deserialization