Deserializing objects is security-sensitive. For example, it has led in the past to the following vulnerabilities:

* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-10654[CVE-2018-10654]: Hazelcast Library: Java deserialization vulnerability
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000058[CVE-2018-1000058]: Jenkins Pipeline: arbitrary code execution vulnerability

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.

== Ask Yourself Whether

* an attacker could have tampered with the source provided to the deserialization function.
* you are using an unsafe deserialization function. See the *Recommended Secure Coding Practices* for examples of safe libraries.

You are at risk if you answered yes to any of those questions.

== Recommended Secure Coding Practices

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:

* ikkisoft's ``++SerialKiller++``
* Apache Commons Class IO's ``++ValidatingObjectInputStream++``
* contrast-rO0's ``++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:

* if it is a file, restrict the access to it.
* if it comes from the network, restrict who has access to the process, such as with a Firewall or by authenticating the sender first.

include::../see.adoc[]

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

include::../message.adoc[]

=== Highlighting

the call to the "readObject", "readUnshared" method on the ObjectInputStream


'''
== Comments And Links
(visible only on this page)

include::../comments-and-links.adoc[]

endif::env-github,rspecator-view[]
