Deserializing objects is security-sensitive. For example, it has led in the past to the following vulnerabilities:
Object deserialization from an untrusted source can lead to unexpected code execution. ObjectInputStream
doesn't provide a way to
apply rules on its InputStream
argument. Knowing that all serializable classes in the scope of the classloader will be deserialized,
there is a possibility that malicious code could be executed during the deserialization phase even if, in the end, a ClassCastException
will be raised.
Deserialization takes a stream of bits and turns it into an object. If the stream contains the type of object you expect, all is well. But if
you're deserializing untrusted input, and an attacker has inserted some other type of object, you're in trouble. Why? There are a few different attack
scenarios, but one widely-documented one goes like this: Deserialization first instantiates an Object
, then uses the
readObject
method to populate it. If the attacker has overridden readObject
then he is entirely in control of what code
executes during that process. It is only after readObject
has completed that your newly-minted Object
can be cast to the
type you expected. A ClassCastException
or ClassNotFoundException
will be thrown, but at that point it's too late.
You are at risk if you answered yes to any of those questions.
To prevent insecure deserialization, you should either use look-ahead deserialization (pre-Java 9) or a filter to make sure you're dealing with the correct type of object before you act on it.
Several third-party libraries offer look-ahead deserialization, including:
SerialKiller
ValidatingObjectInputStream
SafeObjectInputStream
Note that it is possible to set a deserialization filter at the level of the JVM, but relying on that requires that your environment be configured perfectly. Every time. Additionally, such a filter may have unwanted impacts on other applications in the environment. On the other hand, setting a filter as close as possible to the deserialization that uses it allows you to specify a very narrow, focused filter.
You should also limit access to the serialized source. For example:
This rule is deprecated, and will eventually be removed.