

\subsubsection{RQ1: How Frequent are Deserialization Vulnerabilities?}
\label{sec:rq_attack_frequency}
\input{rq_attack_frequency.tex}

\subsubsection{RQ2: How are Gadgets Introduced?}
\label{sec:rq_how_vuln_introduced}
\input{rq_how_vuln_introduced.tex}

\subsubsection{RQ3: How are Gadget Libraries Patched?} 
\label{sec:rq_how_vuln_patched}
\input{rq_how_vuln_patched.tex}

\subsubsection{RQ4: What is the Life-cycle of Gadgets?}
\label{sec:rq_vuln_lifecycle}
\input{rq_vuln_lifecycle.tex}

\subsubsection{RQ5: How are Vulnerabilities Patched in Real-life Applications?}
\label{sec:rq_apps}
\input{rq_app_vulnerabilities}

\subsubsection{RQ6: How easy is the automation of filters against deserialization attacks?}
\label{sec:rq_filters}
\input{rq_filters}


\subsection{Terminology}
 \label{ser-deser-mechanisms}
 
Before starting the study of Java deserialization attacks, we define the terminology used all along this paper. 
 
 \paragraph{\textbf{Vulnerability.}} 
We use Mitre's definition~\cite{MitreVulnerability}: 
\emph{"[A vulnerability is] a flaw in a software, firmware, hardware, or service component resulting from a weakness that can be exploited, causing a negative impact to the confidentiality, integrity, or availability of an impacted component or components."}.
 
 
 \paragraph{\textbf{Gadget and gadget chain.}} 

In the context of this paper, a gadget is a Java method using objects or fields that can be attacker-controlled. A gadget chain is a malicious sequence of method (gadget) calls created by an attacker. The presence of a set of gadgets in the classpath of a vulnerable application is one of the conditions required to carry out deserialization attacks.   
 
\paragraph{\textbf{Deserialization vulnerability in Java.}} 
A Java deserialization vulnerability is a weakness in the code that can be exploited when the Java code deserializes an attacker-controlled byte stream. 
Facilitated attacks, such as arbitrary code execution, have an impact on the confidentiality, integrity, or availability of the system. 
For instance, a \texttt{readObject} method present in a Java program is a weakness that is considered to be a vulnerability when: 
(1) the program containing this method accepts and deserializes data from a source that an attacker can control, and 
(2) the attacker can exploit this weakness. 
In practice (2) requires one to build a gadget chain and thus requires all necessary gadgets to be in classes that are on the classpath of the vulnerable application.
Note that classes containing gadgets do \emph{not need to be used} by the vulnerable program, just must be loadable.
 

\paragraph{\textbf{Gadget library.}}
By a gadget library, we denote a Java library containing one or more gadgets.
A gadget can be used during a deserialization attack when the corresponding gadget library is included in the classpath of the vulnerable application.  

\paragraph{\textbf{Exploit.}}
 An exploit is a piece of software or a sequence of commands that takes advantage of a bug or vulnerability causing a negative impact on the confidentiality, integrity, or availability of an impacted component or components. 


 \paragraph{\textbf{Patch.}}
The  National Institute of Standards and Technology (NIST)~\cite{nistPatch} defines a patch as 
\emph{``a "repair job" for a piece of programming; also known as a "fix". A patch is the immediate solution to an identified problem that is provided to users''}. The patch of a library  \emph{``is not necessarily the best solution for the problem, and the product developers often find a better solution to provide when they package the product for its next release.''}

In the context of Java deserialization vulnerabilities, there are two kinds of patches: patches for vulnerabilities and patches for gadgets.
Patching a gadget library requires one to remove gadgets, thereby disabling attacks relying on this gadget library.
While authors of libraries sometimes decide to make exploitation harder by patching gadget libraries involved in attacks, 
gadgets are ultimately not flaws on their own.
{Most importantly, the gadgets are not themselves the deserialization vulnerabilities, they are rather pieces of code that facilitate the successful exploitation of a deserialization vulnerability that itself frequently resides in application code, not library code.}
One can draw a parallel with memory-corruption vulnerabilities.
Shacham~\cite{Shacham07} mentioned that libraries leveraged to exploit a memory corruption vulnerability are the ``innocent flesh on the bone''.
Thus, it is not surprising that they are rarely patched to address the issue. 
Patches for gadget libraries are similar to the heap-hardening~\citep{HallerKGB16, KuznetsovSPCSS14, Younan15} introduced in memory allocators in response to heap-based buffer overflow exploit techniques: 
they do not patch heap-based buffer overflows, yet they hinder exploitation techniques that have become publicly known.


\paragraph{\textbf{Deserialization attacks.}}
They are performed using two main steps: 
(1) an ahead-of-time \textit{serialization} step during which the attacker builds a customized byte stream specially crafted to execute a chain of gadgets during deserialization and 
(2) an online \textit{deserialization} step executed on the victim's vulnerable machine, and during which this victim's machine will deserialize objects from the attacker-controlled byte stream and thus execute the gadget chain. \\
 
 

\noindent \textit{Illustration.}  
Let us  use the example of Figure~\ref{example-terminology} to clarify the terminology. 
Assume that there is a library called \texttt{libA.jar} containing class \texttt{A} of Figure~\ref{fig:A-terminology}. 
As explained previously in the example of  section~\ref{sec:introduction}, the \texttt{command} field of type \texttt{String} of  class  \texttt{A} can be attacker-controlled. 
This class contains a \textit{gadget}: \texttt{Runtime.exec} (line 19)
 called through another gadget \texttt{readObject} of the same class \texttt{A}. 
The chain \texttt{A.readObject $\rightarrow$ Runtime.exec} is a \textit{gadget chain}. 
The \texttt{libA.jar} library contains these two gadgets and is then considered as a \textit{gadget library}.  
Now suppose that there is a program \texttt{VictimClass} using \texttt{libA.jar} in its classpath as shown in Figure~\ref{fig:B-terminology}. 
The \textit{vulnerability} in this context is that the code uses the \texttt{readObject} to deserialize objects from an untrusted source and that the gadget library \texttt{libA.jar} is in the classpath of \texttt{VictimClass}. An \textit{exploit} may consist in generating a file \texttt{f} by an attacker  in which he/she controls the field \texttt{command} and through which (i.e., when it is given as \texttt{args[0]} in line 6 of  \texttt{VictimClass.main()}) he/she can execute a command "\texttt{calc.exe}" for instance.  
The most secure \textit{patch} for this vulnerability is to not deserialize the untrusted file \texttt{f}. But, another possible patch consisting in  removing the class \texttt{A} from the classpath of the program \texttt{VictimClass} is sufficient to prevent this particular deserialization attack. 


\begin{figure}[htbp]
\centering
\begin{minipage}{.46\textwidth}
\begin{myminted}[linenos=true,xleftmargin=5pt,fontsize=\scriptsize]{Java} 
/* Class A is in libA.jar */
public class A implements Serializable {
// the attacker can change the value of
// the 'command' field during serialization
  String command; 

// in class 'A', the 'command' field
// could be restricted to, e.g., a few values.
// This does not prevent the attacker from
// changing the field to a value of the attacker
// choice during serialization
[...]

  private void readObject() {
// this code is executed during deserialization
// if the attacker controls 'command', he/she 
// can execute arbitrary code on the machine
// deserializing an instance of type 'A'
    Runtime.exec(command); 
  }
}
\end{myminted}
\subcaption{A vulnerable class. (This sub-figure is a modified version of  Figure~\ref{fig:simple-example}.) }
\label{fig:A-terminology}
\end{minipage}
\begin{minipage}{.5\textwidth}
\begin{myminted}[linenos=true,xleftmargin=15pt, fontsize=\scriptsize, highlightlines={12}]{Java}
/* libA.jar is in the classpath of the 
   JVM running VictimClass.main() */
public class VictimClass implements Serializable {
  public static void main (String[] args) 
    FileInputStream fis = 
    	new FileInputStream(args[0]); 
    ObjectInputStream ois = 
    	new ObjectInputStream (fis);
// if the attacker gives an object of type 'A'
// to deserialize, A.readObject is executed
// before the cast to (String)
    String s = (String) ois.readObject();
    ois.close(); 	
  } 
}
\end{myminted}
\subcaption{A class deserializing an input file.} 
\label{fig:B-terminology}
\end{minipage}
\caption{Explanatory example for the terminology.}
\label{example-terminology}
\end{figure}


\subsection{Overview of Typical Deserialization Attacks}
\label{sec:deser-attack}


The requirement for this attack is that the victim machine runs software that deserializes objects from an untrusted byte stream controlled by the attacker.
In a first step, the attacker crafts a specific serialized file $s$ representing a class instance $i$.
Then the attacker sends $s$ to the victim either directly or through the network. 
Once received, the file is deserialized with a \texttt{readObject} method to try to reconstruct instance $i$.
The attack takes place during this deserialization process, when the Java code, 
relying on the attacker-controlled data in the byte stream, executes the attacker's payload. This payload then, for instance, may execute arbitrary code with the process' privileges through a call to \texttt{Runtime.exec()}.
An attack only works if the victim's Java process has all the required vulnerable classes on its \emph{classpath}.


Transforming a class instance $i$ into a byte stream is called serialization.
The basic principle of \emph{de}serialization is to rebuild the same class instance $i$ from the byte sequence. 
Figure~\ref{fig:B-terminology}  shows a short code snippet to illustrate the deserialization process in Java.
This generic Java code represents the software running on the victim machine.
To simplify the code, the byte stream is read from a file and not from the network as in Figure~\ref{fig:B-terminology}.
The first and only argument passed to this program is a path to a file that  represents the serialized data to deserialize.
The Java code opens this file and calls the  method \texttt{readObject()} to deserialize its content (line 12 in Figure~\ref{fig:B-terminology}). 
Observe that while there is a cast to \texttt{String}, the attacker could put a different object type to deserialize.
Indeed, deserialization attacks are triggered during deserialization.
{The cast to the proper type (here \texttt{String}) is only executed \emph{after} the byte stream has been deserialized. 
Thus, the cast operation is executed too late and does not prevent an attack.}
 Observe also that there is no change of the methods \texttt{readObject()} and \texttt{writeObject()} signatures or code. 
 The only changes concern the fields accessible to the attacker. 
 

\begin{figure}
\begin{center}
\begin{myminted}[linenos=false,xleftmargin=0pt,fontsize=\scriptsize, highlightlines={}]{Java} 
15 Runtime.exec()                           // (7)
14 NativeMethodAccessorImpl.invoke0()
13 NativeMethodAccessorImpl.invoke() 
12 DelegatingMethodAccessorImpl.invoke() 	
11 Method.invoke()                          // (6)
10 InvokerTransformer.transform()           // (5)
 9 ChainedTransformer.transform()           // (4) (d)
 8 LazyMap.get()                            // (3) (c)
 7 AnnotationInvocationHandler.invoke()     // (2) 
 6 $Proxy0.entrySet()                       // (2) (b)
 5 AnnotationInvocationHandler.readObject() // (1) (a)
 4 [...] // internal JVM code
 3 ObjectInputStream.readObject0() 
 2 ObjectInputStream.readObject()
 1 VictimClass.main(String[]) 
\end{myminted}
\end{center}
  \caption{Abstraction of call stack of the \texttt{Com\-monsCol\-lections1} attack.} 
 \label{CC1-Call-stack} 
\end{figure}


\subsection{A Concrete Real-World Example}

In this section, we describe the \texttt{Com\-monsCol\-lections1} deserialization attack (from  the ysoserial repository~\cite{ysoserial}).
More precisely, we analyze what happens  when the attack of \texttt{Com\-monsCol\-lections1} is exploited.
The gadgets are present in the 3.1, 3.2 and, 3.2.1 versions of apache commons-collections library. 

\begin{figure}[htbp]
\centerline{\includegraphics[scale=0.45]{sercomponents.png}}
\caption{Components of the serialized byte stream generated by the ysoserial tool and which will be deserialized by the victim class in Figure~\ref{fig:B-terminology}.}
\label{fig:serializedFile}
\end{figure}


As shown in Figure~\ref{fig:serializedFile}, the serialized byte stream \texttt{s} generated for this attack features four main objects:
(a) an \texttt{An\-no\-ta\-tion\-In\-voca\-tion\-Handler}, 
(b) a \texttt{Proxy}, 
(c) a \texttt{LazyMap}, and 
(d) an array of \texttt{Transformers} (a \texttt{ChainedTransformer} object). 
The fields of each concrete object in the byte stream are controlled by the attacker.
During deserialization, the Java code might  choose to execute a branch based on the value 
of the fields controlled by the attacker. 
Furthermore, the Java code might call methods using fields controlled by the attacker.
The latter can thus control part of the execution flow.
In the \texttt{Com\-monsCol\-lections1} attack, objects (a-d) - of both Figures~\ref{CC1-Call-stack} and \ref{fig:serializedFile} - are \emph{chained} to trigger
the execution of the \texttt{Runtime.exec()} method with an attacker-controlled value
to achieve arbitrary code execution.
The call stack of this attack - when its payload is executed -  is represented in Figure~\ref{CC1-Call-stack}. 
This call stack is composed  of a chain of \textit{gadgets}.  A gadget is a  method using objects or fields that can be attacker-controlled. 
To simplify Figure~\ref{CC1-Call-stack}, we do not consider the native calls related to Java  reflection  or the internal workings of the JVM. In the attack in this figure, we consider that there are 7 gadgets: (1) \texttt{AnnotationInvocationHandler.readObject()} which is the head, or the \textit{entry gadget}, of the chain, (2) \texttt{\$Proxy0.en\-try\-Set()}, (3) \texttt{LazyMap.get()}, (4) \texttt{ChainedTran\-sfor\-mer.trans\-form()}, (5) \texttt{In\-vo\-ker\-Trans\-for\-mer.transform()},  (6) \texttt{Method\-.in\-vo\-ke()} which we consider as an \textit{attack gadget} and (7) \texttt{Run\-ti\-me.ex\-ec()} representing the last gadget, the performed attack action.  An attack gadget is a method call  that triggers the payload. In this running example, \texttt{Method.invoke()} calls \texttt{Runtime.exec()} via reflection. 



In this paragraph, we explain step-by-step the different calls in the gadgets chain. When the victim application, represented by the code in Figure~\ref{fig:B-terminology},
deserializes the \texttt{s} byte stream by calling \texttt{readObject} (stack frame 1 in Figure~\ref{CC1-Call-stack}), 
the internal JVM code handling the deserialization is executed (stack frames 2, 3 and 4). Range 4 represents 7 hidden method calls. We do not show them since they represent the internal JVM code related to Java reflection.
This leads to a call of the \texttt{readObject()} method of the first object to deserialize,
which is an \texttt{An\-no\-ta\-tion\-In\-voca\-tion\-Handler} (stack frame 5). 
In the code of this method, there is a field \texttt{this.memberValues} initialized by a \texttt{\$Proxy0}. This is the reason for calling \texttt{\$Proxy0.entrySet()} (frame 6). 

A Proxy in Java is a class generated during runtime to implement interfaces. It is associated with an invocation manager represented by the \texttt{In\-vo\-ca\-tion\-Han\-dler} class. 
The JVM uses reflection to redirect any method calling a Proxy to the  \texttt{in\-vo\-ke()}
method of the interface implemented by this Proxy. 
This explains the jump from \texttt{\$Pro\-xy0.en\-try\-Set()} to \texttt{An\-no\-ta\-tion\-In\-voca\-tion\-Hand\-ler.in\-voke()} (stack frame 7). This method \texttt{invoke()} will look for which method to call. This information is extracted from the serialized \texttt{s} byte stream in which there is a field initialized by the value \texttt{LazyMap}, a class of the commons-collections library. This value is assigned to a field called \texttt{this.memberValues} in the \texttt{invoke} method. This leads to the call of \texttt{LazyMap.get()} (stack frame 8). Until now, the \texttt{LazyMap} is empty. For this reason, the \texttt{get()} method uses a call to a \texttt{factory.transform()} method in order to decorate the \texttt{LazyMap}. Again here, the  \texttt{factory} field is extracted from the serialized \texttt{s} byte stream and is assigned to a \texttt{ChainedTransformer} leading to the call of  \texttt{ChainedTransformer.transform()} (stack frame 9). A \texttt{ChainedTransformer} implements the \texttt{Transformer} interface and contains four transformers: its first element is a \texttt{ConstantTransformer} which is equal to any constant chosen by the attacker, its three subsequent elements are \texttt{InvokerTr\-ans\-for\-mers} and each one of them will take the output of the previous one and transform it. The last \texttt{InvokerTransformer} will transform the attacker command (stack frame 10) into an invoke - by reflection -  of \texttt{Runtime.exec()} (stack frames 11 to 15).  This attack is using the Transformers objects. A \texttt{Transformer} is an interface in Java implemented by one or more other classes that transforms an input object into an output object. Among these classes are \texttt{ConstantTransformer} and
\texttt{InvokerTransformer}. Both of them are implementations of the \texttt{Transformer} interface.  The former allows to always return the same constant without checking the input object. The latter  allows the creation of a new object by reflection and the invocation of a method defined in the class of this object.


The commons-collections library has been patched in version 3.2.2. 
by adding a check on the \texttt{InvokerTrans\-former} object when calling its \texttt{transform()} method (line 10 of the call stack). 
A \texttt{check\-Un\-sa\-feSerialization} method checks whether serialization is enabled for unsafe classes like the \texttt{Transformer}. Otherwise, an exception is thrown. 
Observe that the library has been patched by changing the code of a single gadget (out of the four gadgets required for the attack). While this prevents \emph{this} attack, it does not prevent the reuse of the three untouched gadgets in future attacks. 

\subsection{Scope of our study}

Our work is based on vulnerabilities described by the ysoserial tool. 
In fact, the generation of the serialized files was conducted by the commands described in its repository. This tool is developed and widely adopted by security researchers due to its ease of use for creating proof of concept payloads. It gathers a wide range of exploits that  concern many well-known libraries such as the commons-collections library. We are not aware of any other tools with features comparable to ysoserial.
Yet, the scope of our study is limited to the gadgets described in ysoserial, and as result, we cannot affirm the complete list of gadget libraries. 
Furthermore, the list of actions performed to introduce gadgets in the libraries in Table~\ref{tab:intro-vuln} is not exhaustive. These actions are extracted from the \numprint{19} ~exploits described in ysoserial. 

\subsection{Source code accessibility}

When performing our analysis of the vulnerabilities in Java applications, we encountered some difficulties in finding and obtaining access to the source code of some applications. Once found, the code is sometimes hard to analyze, and finding the patch takes a lot of time. Another limitation regards the inaccessibility of some existing patches for 4 CVEs among our studied \numprint{95}~ ones (4.1\%). Indeed, some applications such as IBM Maximo Asset Management (CVE-2020-4521) present links to patches that are not accessible: an error message is displayed when trying to obtain access to the patch. It is not trivial to extract this patch information in these cases and a reverse engineering step is needed to get such information. For time-related reasons, we could not do this step. Obviously, this harms our study since we cannot identify supplementary patching actions that may be unknown beforehand.   

\subsection{CVEs keyword-based search precision}
The study on the frequency of deserialization vulnerabilities yields an under-approximation of the real-world situation.
Indeed, some CVE might not have the keyword \emph{deseriali[sz]ation} we use for the search and thus might not be present in
the list of CVEs returned from the search.
This is the case for instance for CVE-2021-26858~\footnote{\url{https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-26857}} a .NET deserialization vulnerability used by the HAFNIUM group to run code as SYSTEM on Microsoft Exchange servers~\cite{microhafnium}: the description of this vulnerability on Mitre's website does not mention that it is a deserialization vulnerability.
Such CVE descriptions were incomplete at the time of writing but might be updated to be more precise. 


\subsubsection{Gadgets analysis}

\paragraph{Collecting the dataset.} 

Our experiments involve several elements: the ysoserial tool, libraries, and JVM versions. 

First, since we are referring to attacks that are using malicious files generated by the ysoserial tool, 
we download this tool~\cite{ysoserial}.
Second, we list all the libraries involved in the \numprint{19} ~studied  ysoserial attacks. For  these attacks, there are \numprint{14} ~ libraries involved. We download all the available versions of each library. In total, we have a set of \numprint{1,410} ~jars for all \numprint{14} ~libraries. Note that each library can have hundreds of versions. For example, there is an attack called \emph{Groovy1} which is using the Apache Groovy library. We have downloaded 192 versions of this library.  We have downloaded all the libraries' jars in September 2020. 
The third element of our study is the JVM.
They can be downloaded from the Oracle~\cite{Oracle},  IBM~\cite{IBM}, and the AdoptOpenJDK~\cite{AdoptOpenJdk}  websites. We obtained a dataset of \numprint{147} ~JVM versions containing 137 Oracle and 10 IBM  and OpenJdk versions. 

Our work aims at: 
(1) understanding how deserialization gadgets are introduced and patched in libraries and 
(2) collecting  the list of gadget library versions. 
The second goal is primordial in our work. Indeed, the studied ysoserial attacks are described for only some specific libraries and JVM versions, yet, we have discovered that most gadgets are still present in non-mentioned libraries/JVM versions. 
    

\paragraph{Experimental Setup.}
\label{sec:setup}

In practice, we simulate a Java deserialization attack $A$ by following three steps:
(1) generate a malicious serialized file $MS$ corresponding to the specific attack $A$ using the ysoserial tool;  
(2) create an application including a victim class $V$ that deserializes the malicious input file $MS$ generated in step (1) using the  \texttt{Object\-Input\-Stream.read\-Object()} method; 
(3) add the gadget library(ies) i.e., libraries containing the required gadgets for the attack in the classpath and run the victim class $V$.

Note that even if the program deserializing data from an untrusted source does not directly \emph{use} classes containing gadgets, 
it is nonetheless vulnerable if these classes are on its classpath. This is because these classes can be referenced during deserialization. For instance, the code of Figure~\ref{fig:B-terminology} does not directly use the \texttt{LazyMap} class. However, we observe a call to the method \texttt{get()} on an instance of this class in the  call stack of Figure~\ref{CC1-Call-stack} (call frame number 8) since the commons-collections library (containing this class) is defined in the classpath of this victim code.\\
 
We combine the JVM version (an attack gadget might be present in a JVM)  with the libraries of the attack and run \numprint{256515}~  programs. 
Consider an attack \textit{A} using a library \textit{l}. 
Suppose that \textit{l} has \textit{n} versions. For \textit{A}, we run \textit{$ \numprint{147} \times n$} executions. 
This means that we run each library version on all the \numprint{147}{} JVMs that we have collected. In another case,  an attack \textit{B} can use \textit{$nblibs > 1$} libraries. Suppose that each library \textit{l$_i$} of them has \textit{nbVers[l$_i$]} versions. The total number of executions is the sum of all the executions per library involved in the attack i.e., \[\numprint{147} \times nbVers[l_1] + \ldots +  \numprint{147} \times nbVers[l_i]+ \ldots +  \numprint{147} \times nbVers[l_{nblibs}]\]  
In other terms, for each attack  relying on $n$ library (n $>$ 1),  
we variate one library at once \textit{i.e.,} we fix ($n-1$) library versions that are vulnerable in the studied attack and we variate the versions of the remaining library. 


 Table~\ref{tab:nb-experiments} explains where this ~\numprint{256515}~ number  is coming from: it results from the addition of  all the numbers of executions per attack. For instance,  the CommonsBeanUtils1  attack relies on three libraries: commons-beanutils having 33 versions, commons-collections having 13 versions and commons-logging having 10 versions. For each one of these libraries, we did \textit{$ \numprint{147} \times n$} executions, where \texttt{n} defines the number of versions. At the end, we perform \textit{$ \numprint{147} \times 33 + \numprint{147} \times 13 + \numprint{147} \times 10 = 8232 $} executions for this attack. 
Our goal is to check if these attacks still are possible with these variants and understand what has changed to allow or block the attacks.

We developed a framework to automatically run our experiments and collect the results in log files correlated to each attack. 
For a single attack, there are thousands of log files. Our scripts consist of testing if the concerned combination (of the JVM and  the library(ies) versions) allows two actions to be performed: the serialization and the deserialization. 
If the serialization fails, the deserialization step cannot take place. 

We run all experiments on a machine with 12 x Intel(R) Xeon(R) Bronze 3104 CPU 1.70GHz, 256G of RAM, and the Debian 10.4 OS.

\begin{table*}[t]
  \centering
  \caption{Studied attacks and the number of experiments per attack}
  \resizebox{\textwidth}{!} {

\begin{tabular}{lllll|l}
\toprule
\textbf{Attack name} & \textbf{Lib name} & \textbf{\# lib versions} &  \textbf{\# experiments per lib} & \textbf{\# experiments per attack} & \textbf{Total}\\
\midrule
\emph{BeanShell1} & beanshell & 16 &  147 x 16 = 2352 & 2352 &  \multirow{27}{*}{\textbf{256515}} \\ \cline{2-5} \cline{1-1}
\emph{Clojure} &  clojure  & 145 &  147 x 145 = 21315 & 21315 &  \\
\cline{2-5} \cline{1-1}
\multirow{3}{*}{\emph{CommonsBeanUtils1}} & commons-beanutils & 33  & 147 x 33 = 4851 &  \multirow{3}{*}{4851 + 1911 + 1470 = 8232} & \\ 
\cline{2-4}
 &  commons-collections & 13 & 147 x 13 = 1911 & & \\
 \cline{2-4}
 & commons-logging & 10 & 147 x 10 = 1470 & & \\
\cline{2-5} \cline{1-1}
\emph{CommonsCollections1} &  commons-collections & 13 &  147 x 13 = 1911 & 1911 & \\
\cline{2-5} \cline{1-1}
\emph{CommonsCollections2} &  commons-collections & 13 &  147 x 13 = 1911 & 1911 & \\
\cline{2-5} \cline{1-1}
\emph{CommonsCollections3} &  commons-collections & 13 &  147 x 13 = 1911 & 1911 & \\
\cline{2-5} \cline{1-1}
\emph{CommonsCollections4} &  commons-collections & 13 &  147 x 13 = 1911 & 1911 & \\
\cline{2-5} \cline{1-1}
\emph{CommonsCollections5} &  commons-collections & 13 &  147 x 13 = 1911 & 1911 & \\
\cline{2-5} \cline{1-1}
\emph{CommonsCollections6} &  commons-collections & 13 &  147 x 13 = 1911 & 1911 & \\
\cline{2-5} \cline{1-1}
\emph{CommonsCollections7} &  commons-collections & 13 &  147 x 13 = 1911 & 1911 & \\ 
\cline{2-5} \cline{1-1}
\emph{Groovy1} & groovy & 192 &  147 x 192 =  28224 & 28224 & \\
\cline{2-5} \cline{1-1}
\emph{ROME} & rome & 12 & 147 x 12 = 1764 & 1764 & \\
\cline{2-5} \cline{1-1}
\emph{MozillaRhino1} &  js-rhino & 26 & 147 x 26 = 3822 & 3822 &  \\
\cline{2-5} \cline{1-1}
\emph{MozillaRhino2} &  js-rhino & 26 & 147 x 26 = 3822 & 3822 & \\
\cline{2-5} \cline{1-1}
\multirow{2}{*}{\emph{Spring1}} &  spring-beans & 180  & 147 x 180 = 26460 & \multirow{2}{*}{26460 + 27342 = 53802} & \\ \cline{2-4}
 & spring-core &  186  &  147 x 186 = 27342 & & \\
\cline{2-5} \cline{1-1}
\multirow{4}{*}{\emph{Spring2}} &  spring-core &  186  &  147 x 186 = 27342 & \multirow{4}{*}{27342 + 294 + 1470 + 27930 = 57036} &  \\ \cline{2-4}
 & aopalliance & 2 & 147 x 2 = 294 & & \\ \cline{2-4}
 & commons-logging & 10 & 147 x 10 = 1470 &  & \\ \cline{2-4}
 & spring-aop & 190 & 147 x 190 = 27930 &  & \\
\cline{2-5} \cline{1-1}
 \multirow{2}{*}{\emph{Click1}} & click-nodeps & 8 & 147 x 8 = 1176 & \multirow{2}{*}{1176 + 2940 = 4116}  & \\ \cline{2-4}
 & javax-servlet & 20 & 147 x 20 = 2940 &  & \\
\cline{2-5} \cline{1-1}
 \multirow{2}{*}{\emph{Vaadin1}} & vaadin-server & 199 & 147 x 199 = 29253 & \multirow{2}{*}{29253 + 29253 = 58506}  & \\ \cline{2-4}
 &  vaadin-shared & 199  & 147 x 199 = 29253 &  &\\
\cline{2-5} \cline{1-1}
\emph{JDK7U21} &  & 147 & 147 x 1 = 147 & 147 &   \\
\bottomrule
\end{tabular}
}
\label{tab:nb-experiments}
\end{table*}



\paragraph{Analyzing the results.}
\label{sec:res-analyze}
The results obtained from our experiments are  analyzed by:
\begin{itemize}
\item generating a table for each attack.  In each table, we have the versions of the JVM and of the implicated library(ies). Such table is composed of colored squares  with symbols: if the attack is successful the square is colored with red  and contains the \textit{0} number, otherwise, it is a fail. The failure of an attack might be caused by one of the three reasons: (1) the serialization is performed but the deserialization fails (orange color and the \textit{1} number)  or (2) the serialization fails because of "Unsupported major.minor version" (yellow color and \textit{V} symbol) or (3) the serialization fails because of an "Error while generating or serializing payload" generated by ysoserial (green color and \textit{-} symbol); 

\item then, filtering the results for the failed  attacks. Here distinguish between two reasons: 
either the serialization fails and there is no serialized file to read 
or the serialization succeeded but the deserialization fails.
\end{itemize} 
 


The list of URLs used to download libraries used in the experiments as well as the tables generated by our experiments are all available at \url{https://github.com/software-engineering-and-security/java-deserialization-rce}


\subsubsection{Vulnerable-applications analysis}


Our second study consists in analyzing real-life Java applications containing deserialization vulnerabilities. 
Our goal is to study how vulnerabilities in these applications are patched. 


\paragraph{Collecting the CVEs.}
To collect a suitable set of subject vulnerabilities, we searched specifically for Java deserialization vulnerabilities in the Mitre CVE database~\footnote{\url{https://cve.mitre.org/}}, using two queries: \emph{\{Java, deserialization\}, \{Java, deserialisation\}}.  
We found that there are \numprint{104} ~CVEs.


\paragraph{Analyzing the CVEs.}
Unfortunately, we observe that not all the CVEs resulting from our search are related to deserialization vulnerabilities.
Thus, we manually analyze the description of each CVE to classify them into one of the following three categories:


\begin{enumerate}
\item Deserialization Vulnerability (\emph{DV}): The kind of CVE we target in this paper, which describes an application in which there is a Java deserialization vulnerability (e.g., an attacker uses an entry point such as the \texttt{readObject} method in the application's code to deserialize his/her  untrusted data and carry out the attack).
\item GAdget (\emph{GA}): A CVE that describes a gadget, but not a vulnerability, i.e., there is no entry point for the attacker to carry out the attack.
\item Untrusted Code (\emph{UC}). A CVE that describes a vulnerability in the deserialization mechanism that can be exploited only if the attacker can execute arbitrary Java code.
\end{enumerate}

\begin{figure
\centering

\begin{tikzpicture}

\pie[radius=1.5, text=pin, hide number]{7.7/UC (7.7\%), 91.3/DV (91.3\%), 1/GA (1\%)}

\end{tikzpicture}

\caption{More than 91\% of CVEs found via a search with keywords 
'Java' and 'deseriali[sz]ation' represent real Java deserialization vulnerabilities.}
\label{deser-categories} 
\end{figure}

As represented in Figure~\ref{deser-categories}, we manually classified 
\numprint{95} ~(91.3\%) of these CVEs as DV, 
8   (7.7\%) as UC and 
1   ($\sim$ 1\%) as GA.
This means that the results of our search on Mitre with simple keywords contain noise (about 8\%) that we need to remove.

Table~\ref{tab:app-vuln} in Appendix~\ref{apps-vulnerable} shows a partial analysis of 29 CVEs for vulnerable Java applications.
The complete table with the \numprint{104}~ CVEs is available at \url{https://github.com/software-engineering-and-security/java-deserialization-rce}
 

\subsection{Methodology}
\label{subsec:methodology}
\input{methodology.tex}



\subsection{Experimental Evaluation}
\label{subsec:evaluation}
\input{evaluation.tex}

\section{0pt}{4pt plus 4pt minus 2pt}{4pt plus 2pt minus 2pt}
\titlespacing\subsection{0pt}{4pt plus 4pt minus 2pt}{4pt plus 2pt minus 2pt}
\titlespacing\subsubsection{0pt}{4pt plus 4pt minus 2pt}{4pt plus 2pt minus 2pt}

\newenvironment{myminted}[2][def]
{\IfFileExists{./useminted}{\minted[#1]{#2}}{\scriptsize\verbatim}}
{\IfFileExists{./useminted}{\endminted}{\endverbatim}}

\makeatletter
\let\@authorsaddresses\@empty
\makeatother

\settopmatter{printacmref=false}

\begin{document}

\title{An In-depth Study of Java Deserialization Remote-Code Execution  Exploits and Vulnerabilities}


\author[Imen Sayar]{Imen Sayar$^\dagger$}
\email{imen.sayar@irit.fr}
\affiliation{
  \institution{University of Toulouse} 
  \city{Blagnac} 
  \country{France}
  \postcode{31070}
}
\thanks{$^{\dagger}$Part of this research was conducted when Imen Sayar was at the University of Luxembourg}


\author[Alexandre Bartel]{Alexandre Bartel$^*$}
\email{alexandre.bartel@cs.umu.se}
\affiliation{
  \institution{Umeå University}
  \streetaddress{MIT-Huset}
  \city{Umeå}  
  \country{Sweden} 
}
\thanks{$^{*}$Part of this research was conducted when Alexandre Bartel was at the University of Luxembourg and the University of Copenhagen.}


\author{Eric Bodden}
\email{eric.bodden@uni-paderborn.de}
\affiliation{
  \institution{Paderborn University}
  \city{Paderborn}  
  \country{Germany} 
}

\author{Yves Le Traon}
\email{Yves.LeTraon@uni.lu}
\affiliation{
  \institution{University of Luxembourg}
  \streetaddress{6, rue Richard Coudenhove-Kalergi}
  \city{Kirchberg Campus} 
  \country{Luxembourg}
  \postcode{L-1359}
}


\begin{abstract}

Nowadays, an increasing number of applications uses deserialization. This technique, based on rebuilding the instance of objects from serialized byte streams, can be dangerous since it can open the application to attacks such as remote code execution (RCE) if the data to deserialize is originating from an untrusted source. Deserialization vulnerabilities are so critical that they are in OWASP's list of top 10 security risks for web applications. This is mainly caused by faults in the development process of applications and by flaws in their dependencies, i.e., flaws in the libraries used by these applications. No previous work has studied deserialization attacks in-depth: How are they performed? How are weaknesses introduced and patched?  And for how long are vulnerabilities present in the codebase?
To yield a deeper understanding of this important kind of vulnerability, we perform two main analyses: one on attack gadgets, i.e., exploitable pieces of code, present in Java libraries, and one on vulnerabilities present in Java applications. 
For the first analysis, we conduct an exploratory large-scale study by running \numprint{256515} ~experiments in which we vary the versions of libraries for each of the \numprint{19}{} publicly available exploits.
Such attacks rely on a combination of \emph{gadgets} present in one or multiple Java libraries. A gadget is a method which is using objects or fields that can be attacker-controlled.
Our goal is to precisely identify library versions containing gadgets and to understand how gadgets have been introduced and how they have been patched.
We observe that the modification of one innocent-looking detail
in a class -- such as making it \texttt{public} -- can already introduce a gadget. Furthermore, we noticed that among the studied libraries, 37.5\%  are not patched, leaving gadgets available for future attacks. 

For the second analysis, we manually analyze 104 deserialization vulnerabilities CVEs to understand how
vulnerabilities are introduced and patched in real-life Java applications.
Results indicate that the vulnerabilities are not always completely patched or
that a workaround solution is proposed.
With a workaround solution, applications are still vulnerable since the code itself is unchanged. 


\end{abstract}

\keywords{serialization, deserialization, vulnerabilities, gadget, remote code execution RCE}

\maketitle


\section{Introduction}
\label{sec:introduction}
\input{introduction.tex}

\section{Background}  
\label{sec:insecure-deserialization}
\input{insecure-deserialization.tex}

\section{Experimentation and Evaluation}
\label{sec:methodandeval}
\input{methodology_and_evaluation.tex}

\section{Synthesis and Take-away Messages}
\label{sec:synthesis}
\input{synthesis.tex}

\section{Limitations}
\label{sec:limitations}
\input{limitations.tex}

\section{Related work}
\label{sec:state-art}
\input{state-art.tex}

\section{Conclusion}
\label{sec:conclusion}
\input{conclusion.tex}

\section*{Acknowledgments}
This work was supported by the Luxembourg National Research Fund (FNR) ONNIVA
Project, ref. 12696663.
This work was partially supported by
the Wallenberg AI, Autonomous Systems and Software Program (WASP) funded by the
Knut and Alice Wallenberg Foundation.



\bibliographystyle{splncs04}
 







\subsection{Deserialization vulnerabilities}

Preventing deserialization attacks starts right at the serialization step.
As explained in~\cite{LawrenceBestPractices}, at this stage it is important to follow recommendations and best practices for the secure use and implementation of Java serialization. Some tips are given to make the code more secure such as (1) guard sensitive data fields; 
 (2) check all security permissions for serialization and deserialization carefully and (3) use serialization filtering for untrusted data. 
The detection of this kind of vulnerability may be attempted early in the software development process.
In this context, Koutroumpouchos \textit{et al.}~\cite{Koutroumpouchos19} have  developed a dynamic tool called \textit{ObjectMap} allowing the detection of deserialization  and object injection vulnerabilities in Java and PHP-based web servers. 
Their tool accepts as inputs a URL of such a web server and generates HTTP requests containing payloads of known attacks. 
Executing these requests enables to detect if the web server is vulnerable to known attacks. 
If one of the payloads is executed it means that a vulnerability has been executed and that the web server needs to be patched.

Frohoff \textit{et al.}~\cite{ysoserial} have implemented the ysoserial tool 
which provides \numprint{34}{} publicly available Java deserialization payloads. 
These payloads represent gadget chains discovered in common Java libraries that can, under the right conditions, exploit Java applications performing unsafe deserialization of objects. When used, these payloads  lead to attacks that are critical since they allow, in most cases, the execution of arbitrary code. 
And even when attacks are unable to execute \emph{arbitrary} code, they may still be able to upload and delete files on the target host or send network traffic such as DNS requests. 
Arbitrary-code execution is the most common and most severe form of an attack since it is the first step  allowing the attacker to compromise the whole machine. 

In the same context, Haken has presented his tool \textit{Gadget Inspector}~\cite{gadgetinspector} to inspect Java libraries and classpaths for gadget chains. This tool allows to automatically detect possible gadgets chains in an application's classpath. Given war or jar file(s) of a library as input, this tool will go through several stages of classpath inspection to build up a list of blocks of gadget chains.  These blocks may exist in the full gadget chains discovered by ysoserial. Exploring the serialized byte streams to deserialize is relevant and may help to detect and locate some gadgets' information. In this context,  Bloor has developed a  tool named \emph{SerializationDumper}~\cite{SerializationDumper} which aims at automating the task of  decoding raw serialization streams and allows, then, to rebuild Java serialization streams and Java RMI packet contents in a more human-readable format. Unfortunately, this tool has some limitations like its inability to deserialize all Java serialized data streams and its "rebuild" mode which only operates on the Hex-Ascii encoded bytes from the dumped data. The same developer has provided another tool called \emph{DeserLab}~\cite{DeserLab}, a Java client and server application that implements a custom network protocol using the Java serialization format to demonstrate Java deserialization vulnerabilities.


Rasheed \textit{et al.} \cite{RasheedD20} propose a hybrid approach
that extends a static analysis with fuzzing to detect serialization
vulnerabilities. They use a heap abstraction to direct fuzzing for vulnerabilities in Java libraries.
Fingann~\cite{Fingann2020} presents  an overview of Java deserialization vulnerabilities, different techniques an attacker can use to exploit these vulnerabilities as well as which mitigation strategies can be employed to minimize the attack surface. 
This thesis encompasses the description of the most known works in the state of the art around deserializations vulnerabilities in Java: the Waratek description of deserialization problem~\cite{WaratekDeserProblem}, the tools like ysoserial~\cite{ysoserial} and Gadget Inspector~\cite{gadgetinspector}, the deserialization gadgets and chains of gadgets~\cite{RuntimeGadget}, and  the code practices to prevent deserialization attacks~\citep{PreventDeserVuln, JavaDeserializationSecurityFAQ}.  

Combating the deserialization attacks is one of the ideas explored by Seacord who examines in~\cite{seacord2017combating} Java deserialization vulnerabilities and evaluates various look-ahead object input streams solutions. 
Cristalli \textit{et al.}~\cite{CristalliVBL18} propose a sandboxing approach  for protecting Java applications based on a trusted execution path used for defining the deserialization behavior. 
They test their defensive mechanism on two Java frameworks, JBoss and Jenkins. They  design a sandbox system that is able to
intercept native methods by modifying the JVM internals.  Their sandboxing system performs two high-level phases: (1) dynamically analyzing Java applications and extracting the precise execution path in terms of stack traces, and
(2) use of a sandbox policy for monitoring applications at runtime and blocking incoming attacks: "\textit{when a native method is invoked by the application, the system intercepts it and checks whether the entire stack trace executed has been already observed in the learning phase. For this check, the system maintains a memory structure in the form of a hash table}"~\cite{CristalliVBL18}. \\


Deserialization vulnerabilities are not limited to the Java language. 
Shahriar \textit{et al.}~\cite{ShahriarH16} propose an approach to discover Object Injection Vulnerability (OIV) in PHP web applications. This kind of vulnerabilities involves accepting external inputs during deserialization operation. They use the concept of Latent Semantic Indexing (LSI~\cite{0021593}) to identify OIVs. Their approach was evaluated using three open-source PHP applications and was able to find the known OIV and to discover new vulnerabilities.


Dietrich \textit{et al.}~\cite{dietrich2017} study  serialization-related vulnerabilities for Java that exploit the topology of object graphs constructed from classes of the standard library. The deserialization, in this case, leads to resource exhaustion and denial of service
attacks. They analyze three vulnerabilities that can be exploited to exhaust stack memory, heap memory, and CPU time. They identify the language and library design features that enable these vulnerabilities. They demonstrate that these  Java vulnerabilities may  concern also C\#, JavaScript, and Ruby.


Peles \textit{et al.}~\cite{Peles2015} present high severity vulnerabilities in Android. One of these vulnerabilities concerns  the Android Platform and Google Play Services and allows arbitrary code execution. They perform a large-scale experiment over 32 701 Android applications and find new 
deserialization vulnerabilities unknown before. They demonstrate the impact of  the detected  vulnerabilities by developing a proof of concept exploit running under Google Nexus 5 Hammerhead running Android 5.1.1.
 

Alexopoulos \textit{et al.}~\cite{AlexopoulosHSM20}  presented a detailed analysis of the large body of open-source software packaged in the popular Debian GNU/Linux distribution. 
Vasquez \textit{et al.}~\cite{VasquezBE17} provided a study of Android-related vulnerabilities focusing on the ones affecting the Android OS. They have studied and classified 660 vulnerabilities. They have classified the  deserialization of untrusted data in a category called  "Indicator of poor quality code". 
The same goal was tackled by Mazuera \textit{et al.}~\cite{Mazuera-RozoBLR19} who  presented a large study aiming at analyzing software vulnerabilities in the Android OS. They analyzed 1235 vulnerabilities from different perspectives: vulnerability types and their evolution, CVSS vectors that describe the vulnerabilities, impacted Android OS layers, and their survivability across the Android OS history. 
 


Other approaches against deserialization attacks suggest to use alternative data formats like textual ones (XML and JSON for example). The deserialization process using these formats does not invoke calls to gadgets, but, Fingann and  Muñoz et al.\citep{blackhatxml,Fingann2020} show that attackers may be able to perform their attacks regardless of the malicious data format.
XMLEncoder/XMLDecoder~\cite{xmlencodecodoc} is one of the existing mechanisms for using  alternative data formats like textual ones.
 While the XMLEncoder class is assigned to write output files for textual representation of Serializable objects, the XMLDecoder class reads an XML document that was created with XMLEncoder~\cite{redhatdeser}. The use of these alternative serialization mechanisms is not necessarily an effective solution to prevent  deserialization attacks. In fact,  Fingann ~\cite{Fingann2020} states that if an application uses XMLDecoder to deserialize a user byte stream, then the user may find another way to inject arbitrary code into the methods to call when deserializing the byte stream.  This means that any application  that uses  user input data to  deserialize by XMLDecoder  can be a victim of deserialization attacks. 


Kyro~{\cite{kyro}} is an alternative Java implementation for serialization.
Similarly to the native Java implementation~{\cite{riggs1996pickling}}, it can lead to 
arbitrary code execution~{\cite{nist-CVE-2020-5413}}.

ProtocolBuffers~{\cite{protobufs}} is a generic approach to serialize any structured data.
It is available in many programming languages such as Java, Python, or C++.
Applications leveraging this serialization protocol might become vulnerable if they manipulate 
sensitive types such as {\texttt{java.lang.reflect.Method}}.
On top of that, the ProtocolBuffers' Java implementation itself was vulnerable to a 
denial of service attack~{\cite{nist-CVE-2021-22569}}. 


Java deserialization filtering is the technique supported by Oracle~\cite{JavaDeserFilter}. 
Filters can validate incoming classes before they are deserialized by screening the  incoming streams of serialized objects.
For each new object in the stream that will be deserialized, the filters are invoked.
Support for serialization filters is included in Java 6 update 141, Java 7 update 131, Java 8 update 121, and all versions after Java 9.
Again, this technique requires the developer to manually extract serializable classes and add patterns to configure and activate the filter. \\ 

\subsection{Java Security}

Balzarotti \textit{et al.}~\cite{BalzarottiCFJKKV08} present an approach that  combines static and dynamic analysis techniques to identify faulty sanitization procedures that can be bypassed by an attacker through sensitive sinks in applications. The authors validate their approach by implementing the \textit{Saner} tool aiming at  analyzing the use of custom sanitization routines to identify possible XSS and SQL injection
vulnerabilities in web applications. They applied it to five real-world applications in  which they identify 13 vulnerabilities: for each sink, there exists at least one program path such that the output of a sanitization routine flows into this sink.
A systematic in-depth study of 87 publicly available Java exploits was performed in~\cite{HolzingerTBB16}. These attacks lead to security vulnerabilities that involve issues such as type confusion, deserialization issues, trusted method chaining, or confused deputies. Holzinger \textit{et al.}~\cite{HolzingerTBB16} show that all attack vectors implemented by the exploits belong to one of three categories: single-step attacks, restricted-class attacks, and information hiding attacks. They studied in detail the structures offered by the Java language such as the Security Manager feature and show how the analysis of the exploits samples helps for the detection of vulnerabilities.


Safe development of applications in Java relies a lot on the robustness of the JVM on which the code will be compiled and executed. 
Yuting \textit{et al.}~\cite{ChenSS19} dealt with the problem of validating the production of JVMs. 
The \textit{classfuzz} fuzzer allows the generation of illegal bytecode files that aim to test a JVM and  detect bugs in its bytecode verifiers. They developed their approach named \textit{classming} in the same context of validating JVMs. Their method is based on a technique called \textit{live bytecode mutation} able to generate mutant bytecode files from a seed bytecode file to test JVMs. They tested their approach on several  JVM implementations and reported the detected JVM crashes. One of their discoveries touches on a highly critical security vulnerability in Java 9 that allowed untrusted code to disable the Security Manager and elevate its privileges.
Confuzzion~\cite{2021confuzzion} is another JVM fuzzer which is more generic in the sense that it allows the generation of programs that are not possible to generate with Classming or Classfuzz.
Dean \textit{et al.}~\cite{DeanFW96} demonstrated that there is a significant number of flaws in the Java language and in these two browsers supporting it. They evoked the compromise that exists between the openness  desired  by  Web application writers and the security needs of their users. Their study aimed at finding the source of the identified flaws. They showed that the difference between the Java language and the bytecode semantics is one of the main reasons for weaknesses affecting the applications. A deeper study  of the bytecode and  bugs concluded that the Java system needs to be reviewed: the bytecode format and the runtime system should be redesigned in order to build a more secure system. 


Holzinger \textit{et al.}~\cite{holzinger2017hardening} conducted a tool-assisted adaptation of the Java Class Library (JCL) able to  significantly harden the JCL against attacks. They study the problem of using shortcuts, originally introduced for ease of use and to improve performance, that cause Java to elevate the privileges of code implicitly. These shortcuts are responsible for a group of vulnerabilities known to have been exploited for the Java runtime: they directly enable attack vectors and complicate the security-preserving maintenance and evolution of the codebase by elevating privileges to certain callers implicitly. Their approach consists of three steps: (1) locate all shortcuts; (2) remove the shortcuts found and (3) wrap the calls in the JCL to those methods that formerly implemented shortcuts into privileged actions. 
Bartel \textit{et al.}~\cite{BartelKT19} presented an approach  based on a runtime solution called \textit{MUSTI}. This tool detects and prevents  invalid object initialization attacks. To achieve this goal, the authors patch the JVM by instrumenting the generated bytecode with an added code. This code checks if the objects have been correctly initialized. Their approach is generic and can be implemented in many languages supporting a similar sandbox system as the JVM.
 Any native code in Java programs may bypass the memory protection and the higher-level policies. To deal with these problems, Chisnall \textit{et al.}~\cite{chisnall2017cheri} developed a hardware-assisted implementation of the Java Native Interface (JNI), called CHERI JNI. This tool extends the guarantees required for Java’s security model to native code. Their approach  ensures  safe direct access to buffers owned by the JVM. 
\subsection{Persistent deserialization of untrusted data}
The deserialization of untrusted data is not recommended by the  OWASP: "the only safe architectural pattern is not to accept serialized objects from untrusted sources or to use serialization mediums that only permit primitive data types."~\cite{owaspDeserPrevention}~\cite{hdivDeserPrevention}. The same advice is provided by the Secure Coding Guidelines for Java SE which  states,  at the beginning of its 8th section, that "Deserialization of untrusted data is inherently dangerous and should be avoided"~\cite{SCGJSE2020}. However, our analysis of Java applications shows that, until now, developers are still using deserialization of data from untrusted sources.
This could be explained by developers not being aware of the recommendations, a lack of proper security vetting mechanisms during software development,
or constraints imposing the use of insecure legacy code.


\subsection{Disable Serializable}

When analyzing the gadget patches (see Table~\ref{tab:patch-vuln}), we find that disabling  the deserialization, by removing the \texttt{java.io.Serializable} interface from the list of implemented interfaces in the application's class(es), prevents exploitation in every single case. Removing this interface is very effective to protect against the known  deserialization attacks  since it breaks the chain of gadgets in the victim application at hand. The other solutions, such as changing the library versions in dependencies, or blocking the access to some ports, can significantly reduce the risk of exploitation but do not remove the weakness.


\subsection{Library use frequency vs. duration of finding patches}
A large fraction of libraries,like the click-nodeps and the javax-servlet, or applications is never patched. Some libraries, like  the commons-collections3, have been  deprecated and replaced by other releases (collections4 in the case of commons-collections). In the other cases, the patch takes many years to be carried out. This points to an important question: Is there a link between the frequency of using a library in real-world applications and the duration to fix its gadgets? In other words, if a library containing gadgets is used in many applications, do developers find the gadgets and fix them more quickly than for other unsafe libraries that are only infrequently used?  We have found a first element to answer this question: the frequency of using a library in applications is not the main factor impacting the duration of finding a patch. For example, commons-collections is used in many real-world applications, yet it was unsafe between 2004 and 2015 and only then, after 11 years, the patch was introduced to fix its gadgets in both deprecated version 3.2.2 and its release 4.4.1.

\subsection{Definition of deserialization vulnerabilities in CVEs}
The definition of deserialization vulnerabilities in CVEs is not precise. In fact, we have found that some declared deserialization vulnerabilities CVEs are in reality not vulnerabilities but rather  descriptions of gadgets (there is no entry point for the attacker to carry out the attack) or descriptions of untrusted code (vulnerability in the deserialization mechanism which can be exploited only if the attacker can execute arbitrary Java code).



\subsection{Gadgets inspection}
A usable take-away from our analysis results is the list of recommendations library developers should follow to prevent the introduction of gadgets. 
These recommendations are inferred from Table~\ref{tab:intro-vuln}. 
When a developer introduces a new class that can be serialized or modifies an existing one (see Table~{\ref{tab:intro-vuln}} for real-world examples), we suggest the following recommendations:
\begin{itemize}
 \item List all the new field types and sub-types which are introduced or modified.
 \item For each type, check that there is no code reachable from the \texttt{readObject} method which enables either to (1) jump to a known gadget or (2) execute code based on the untrusted data (e.g., a reflective method call with the method description extracted from the untrusted input).
\end{itemize}
