FlawOpen

flawopen.com/Java deserialization/ObjectInputStream safety

Is Java ObjectInputStream safe for untrusted data?

Java security reference
Plain English

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.

RISKY: native object deserialization
// Do not pass attacker-controlled bytes here.
try (var in = new ObjectInputStream(untrustedStream)) {
    Object value = in.readObject();
    handle(value);
}
SAFER: parse a fixed data type
// 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

Frequently asked question

Does adding an ObjectInputFilter make readObject() safe?

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

See also Insecure Deserialization: Risks and Remediation Newtonsoft.Json TypeNameHandling: Safe Configuration? PHP unserialize() and Untrusted Input Python pickle.load() Security: Untrusted Data Risks Is Ruby YAML.load Safe? Psych Versions & Safe Loading .NET BinaryFormatter Security: Risks and Migration