Imen Sayar

Alexandre Bartel

An In-depth Study of Java Deserialization Remote-Code Execution Exploits and Vulnerabilities

Keywords: serialization, deserialization, vulnerabilities, gadget, remote code execution RCE

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 256 515 experiments in which we vary the versions of libraries for each of the 19 publicly available exploits. Such attacks rely on a combination of 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 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.

Introduction

Over the past 10 years, the MITRE Corporation [START_REF] Corporation | [END_REF] registered 364 CVEs linked to deserialization vulnerabilities 1 in several mainstream programming languages such as Java, PHP, and .NET. These critical vulnerabilities, frequently allowing Remote Code Execution (RCE), are a highly relevant topic in the research community. For instance, Shcherbakov et al. [START_REF] Shcherbakov | Serialdetector: Principled and practical exploration of object injection vulnerabilities for the web[END_REF] recently developed an opensource tool named SerialDetector allowing the detection of deserialization vulnerabilities in .NET applications. In this paper, we focus on the characterization of Java deserialization vulnerabilities. These vulnerabilities result because of flaws existing in the applications' development process or in the libraries used by these applications.

Java serialization allows transforming class instances into a stream of bytes. Java objects can therefore be transferred through a network. Deserialization consists of reading the serialized byte stream in order to rebuild the original instances by loading their fields. While serialization is convenient to transfer objects between hosts, it presents a danger when the source of the data to deserialize is untrusted. Indeed, an attacker could craft a byte stream that, when deserialized on the remote host, could control the execution flow of the Java code by chaining sequences of Java code called gadgets. A deserialization attack can be performed by leveraging either gadgets present in the Java Class Library (JCL) or in an external library or by combining many libraries containing gadgets, that we will refer to as gadget libraries in the remainder of this paper.

Figure 1 shows a simple example of a Java serializable class A characterized by a String field called command. When calling the writeObject method, suppose that the attacker changes this field with the Linux command line top (line number 6). The execution of readObject leads to the call of the gadget Runtime.exec (line 9) which is using the attacker-controlled object command. A simple example of a serializable class. In this class, the attacker can modify the command field. Thus, during deserialization, when the JVM calls A.readObject() method, the attacker command will be executed instead of "top".

In 2015, Frohoff and Lawrence demonstrated how to exploit unsafe Java deserialization vulnerabilities [START_REF] Lawrence | Owasp appseccali 2015 -marshalling pickles[END_REF]. The same year, Litchfield [START_REF] Raghavan | Lessons learned from the java deserialization bug[END_REF] and Stepankin [START_REF] Stepankin | remote code execution vulnerability[END_REF] identified an RCE Java deserialization vulnerability in one of PayPal's critical applications, the manager portal 2 which could allow attackers to reach production databases. In 2016, an attacker took control of 2 000 computers of the Metropolitan Transport Agency of San Francisco through a Java deserialization vulnerability in the Web server [START_REF] Guardian | San francisco municipal transport agency attacked by hackers who locked up computers and data with 100 bitcoin demand[END_REF]. Equifax3 had one of its worst bugs in 2017 when attackers infiltrated its network and stole the personal information of 147.7 million Americans from its servers. The entry point of this attack was CVE-2017-9805, a Java deserialization vulnerability in Apache Struts' web application [START_REF] Ng | How the equifax hack happened, and what still needs to be done -a year after the revelation of the massive breach, there's unfinished business[END_REF]. All these concrete real-world examples support the conclusion of multiple studies [START_REF] Blazquez | Insecure deserialization: Attack examples, mitigation and prevention[END_REF][START_REF]Owasp top ten[END_REF] ranking insecure deserialization in the top 10 of the most dangerous web application security vulnerabilities. More precisely, in 2021, OWASP classifies this kind of vulnerability in the 8th position after other dangerous vulnerabilities like Cross-Site Scripting (XSS) [52] -classified as the third most dangerous vulnerability-or buffer overflow [START_REF]OWASP: Buffer overflow[END_REF]. We study this problem of deserialization attacks because -compared to other vulnerabilities-a deserialization attack is able to completely control the victim systems or to give place to ransomware attacks. For instance, on one hand, a buffer overflow on modern operating systems will not give the attacker anything on its own because it needs to be chained with at least an information leak and other vulnerabilities to bypass other mitigation techniques. On the other hand, a deserialization vulnerability is at a higher level and might allow the attacker a complete control over the target system. Another important aspect is that "dormant" serialization vulnerabilities can be super easily enabled, once new gadgets are accidentally introduced. To our point of view, it is much more subtle than other kinds of vulnerabilities such as injections.

In this paper, we study Java gadgets and Java deserialization vulnerabilities found in real-world applications leveraging the standard Java deserialization mechanism [START_REF] Riggs | Pickling state in the java system[END_REF]. The first study is based on the analysis of gadgets from 19 publicly available remote code execution (RCE) attacks from the ysoserial Github repository [START_REF] Frohoff | ysoserial[END_REF]. Ysoserial is a project that gives a proof of concept tool and provides [START_REF] Java | [END_REF] Java payloads exploited in publicly known deserialization attacks. These latter are carried out by chaining gadgets. In this paper, we focus on 19 RCE attacks representing the majority of the ysoserial attacks. Our study is limited to this kind of attacks because we have developed a framework detecting RCE attacks only. The second study is based on the manual analysis of 77 Java applications impacted by a Java deserialization vulnerability described in a CVE 4 . We found that for all attacks relying on a single gadget library, this library has been patched. The patching action can impact one or many gadget libraries involved in an attack, i.e., when the attack relies on multiple gadget libraries, patching a single library may be sufficient to avoid this attack. Yet, the non-patched gadget libraries can often still be leveraged later if they can be combined with other gadgets. Thus, even though they might not lead to an exploitable software at the time, they do increase the attackers' capabilities, thus weakening the software system. One aspect of our analysis is the detection of recent gadget library versions. This is relevant since it points to recent library versions non-cited in ysoserial repository, like the commons-beanutils, that still contain gadgets. This may alert developers to be aware of these gadgets' library versions if used in the classpath of their applications and to check if the concerned library versions are mentioned as gadgets ones in CVEs database.

Furthermore, this paper analyzes how gadgets are introduced into libraries-an important point that previous pieces of research did not explicitly address. When analyzing the 19 RCE exploits, we have identified several ways to introduce a gadget in a library: adding classes, methods, and interfaces, or changing the signature of methods. Our main conclusion is that the modification of one innocent-looking detail in a class -such as making it public -can already introduce a gadget. When studying patches of such libraries, we observed that the time used to remove gadgets varies between several months and almost 12 years, with an average of almost six years. It thus appears that deserialization vulnerabilities do not yet get the attention of practitioners that they should actually deserve.

The study on Java applications clearly shows that developers should never write code that deserializes data from an untrusted source because it becomes an obvious entry point for attackers. Solutions exist to prevent knows attacks, e.g. allow/deny lists, but they are not fool-proof, as the complete list of gadgets present in Java libraries is unknown. Interestingly enough, for 24.1% of the studied CVEs, the solution that has been selected to prevent the exploitation of the vulnerability is not a code change but a workaround. Workarounds work well on an already deployed system, however, they might not be applied in new deployments or in a new software environment, which makes the vulnerability accessible to the attacker again.

This paper is concerned with how deserialization vulnerabilities in Java manifest in practice. We present the following contributions:

• We conduct a large-scale study on more than 256 515 combinations of 14 libraries, representing 19 publicly known Java deserialization RCE exploits, and 147 Java runtimes to understand which precise library versions introduce gadgets, how they are patched, and the structure of attacks in terms of gadgets. A thorough description of the experimental procedure used to obtain the experimentation data, including how test subjects were collected, is also described. • We detail how deserialization gadgets are introduced in the libraries. To our knowledge, this is the first work to consider how deserialization vulnerabilities manifest in real code bases and libraries. This provides some insight into how these vulnerabilities are commonly treated outside of academia. • Based on the results of our analysis on how gadgets are introduced, we propose recommendations for library developers to prevent the introduction of gadgets. • We perform a study of the patching time of some libraries and show that it can sometimes take over 10 years. • We perform an analysis of 104 Mitre CVEs that concern deserialization vulnerabilities in Java applications and conclude that not all the patches prevent the attacks and protect the applications.

The remainder of this paper is organized as follows. Section 2 presents background about essential concepts related to Java deserialization vulnerabilities and uses an example to explain how a deserialization attack can be performed. Section 3 explains our methodology and details our two analyses: the large-scale study about attack gadgets present in Java libraries and the analysis of vulnerabilities present in Java applications with regard to the libraries and JVM versions. Take-away messages and lessons learned from our analyses are described in Section 4. Section 5 points on the limitations of our approach. The state of the art is discussed in Section 6. Finally, Section 7 concludes this work.

Background

Terminology

Before starting the study of Java deserialization attacks, we define the terminology used all along this paper.

Vulnerability. We use Mitre's definition [START_REF] Corporation | Terminology -a glossary of terms used by the cve program[END_REF]: "[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. ".

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.

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 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 not need to be used by the vulnerable program, just must be loadable.

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.

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.

Patch. The National Institute of Standards and Technology (NIST) [START_REF] Tracy | Guidelines on electronic mail security[END_REF] defines a patch as "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 "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 [START_REF] Shacham | The geometry of innocent flesh on the bone: return-into-libc without function calls (on the x86)[END_REF] 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 [START_REF] Haller | METAlloc: efficient and comprehensive metadata management for software security hardening[END_REF][START_REF] Kuznetsov | Code-Pointer Integrity[END_REF][START_REF] Younan | FreeSentry: protecting against use-after-free vulnerabilities due to dangling pointers[END_REF] 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.

Deserialization attacks. They are performed using two main steps: (1) an ahead-of-time 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 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.

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

Overview of Typical Deserialization Attacks

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 𝑠 representing a class instance 𝑖. Then the attacker sends 𝑠 to the victim either directly or through the network. Once received, the file is deserialized with a readObject method to try to reconstruct instance 𝑖. 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 Runtime.exec(). An attack only works if the victim's Java process has all the required vulnerable classes on its classpath.

Transforming a class instance 𝑖 into a byte stream is called serialization. The basic principle of deserialization is to rebuild the same class instance 𝑖 from the byte sequence. Figure 2b 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 2b. 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 readObject() to deserialize its content (line 12 in Figure 2b). Observe that while there is a cast to 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 String) is only executed 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 readObject() and writeObject() signatures or code. The only changes concern the fields accessible to the attacker.

A Concrete Real-World Example

In this section, we describe the CommonsCollections1 deserialization attack (from the ysoserial repository [START_REF] Frohoff | ysoserial[END_REF]). More precisely, we analyze what happens when the attack of CommonsCol-lections1 is exploited. The gadgets are present in the 3.1, 3.2 and, 3.2.1 versions of apache commons-collections library. As shown in Figure 4, the serialized byte stream s generated for this attack features four main objects: (a) an AnnotationInvocationHandler, (b) a Proxy, (c) a LazyMap, and (d) an array of Transformers (a 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 CommonsCollections1 attack, objects (a-d) -of both Figures 3 and4 -are chained to trigger the execution of the 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 3. This call stack is composed of a chain of gadgets. A gadget is a method using objects or fields that can be attacker-controlled. To simplify Figure 3, 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) AnnotationInvocationHandler.readObject() which is the head, or the entry gadget, of the chain, (2) $Proxy0.entrySet(), (3) LazyMap.get(), (4) ChainedTransformer.transform(), (5) InvokerTransformer.transform(), (6) Method.invoke() which we consider as an attack gadget and (7) Runtime.exec() representing the last gadget, the performed attack action. An attack gadget is a method call that triggers the payload. In this running example, Method.invoke() calls 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 2b, deserializes the s byte stream by calling readObject (stack frame 1 in Figure 3), 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 readObject() method of the first object to deserialize, which is an AnnotationInvocation-Handler (stack frame 5). In the code of this method, there is a field this.memberValues initialized by a $Proxy0. This is the reason for calling $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 InvocationHandler class. The JVM uses reflection to redirect any method calling a Proxy to the invoke() method of the interface implemented by this Proxy. This explains the jump from $Proxy0.entrySet() to AnnotationInvocationHandler.invoke() (stack frame 7). This method invoke() will look for which method to call. This information is extracted from the serialized s byte stream in which there is a field initialized by the value LazyMap, a class of the commons-collections library. This value is assigned to a field called this.memberValues in the invoke method. This leads to the call of LazyMap.get() (stack frame 8). Until now, the LazyMap is empty. For this reason, the get() method uses a call to a factory.transform() method in order to decorate the LazyMap. Again here, the factory field is extracted from the serialized s byte stream and is assigned to a ChainedTransformer leading to the call of ChainedTransformer.transform() (stack frame 9). A ChainedTransformer implements the Transformer interface and contains four transformers: its first element is a ConstantTransformer which is equal to any constant chosen by the attacker, its three subsequent elements are InvokerTransformers and each one of them will take the output of the previous one and transform it. The last InvokerTransformer will transform the attacker command (stack frame 10) into an invoke -by reflection -of Runtime.exec() (stack frames 11 to 15). This attack is using the Transformers objects. A 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 ConstantTransformer and InvokerTransformer. Both of them are implementations of the 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 InvokerTransformer object when calling its transform() method (line 10 of the call stack). A checkUnsafeSerialization method checks whether serialization is enabled for unsafe classes like the 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 this attack, it does not prevent the reuse of the three untouched gadgets in future attacks.

Experimentation and Evaluation 3.1 Methodology

In this part, we explain how we proceed to perform the two types of analysis: on gadgets and on real-world Java applications.

Gadgets analysis

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 [START_REF] Frohoff | ysoserial[END_REF]. Second, we list all the libraries involved in the 19 studied ysoserial attacks. For these attacks, there are 14 libraries involved. We download all the available versions of each library. In total, we have a set of 1,410 jars for all 14 libraries. Note that each library can have hundreds of versions. For example, there is an attack called 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 [START_REF]Oracle: Oracle se downloads[END_REF], IBM [START_REF] Company | Ibm download[END_REF], and the AdoptOpenJDK [START_REF]OpenJ9: Openj9 download[END_REF] websites. We obtained a dataset of 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.

Experimental Setup. In practice, we simulate a Java deserialization attack 𝐴 by following three steps: (1) generate a malicious serialized file 𝑀𝑆 corresponding to the specific attack 𝐴 using the ysoserial tool; (2) create an application including a victim class 𝑉 that deserializes the malicious input file 𝑀𝑆 generated in step (1) using the ObjectInputStream.readObject() 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 𝑉 .

Note that even if the program deserializing data from an untrusted source does not directly 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 2b does not directly use the LazyMap class. However, we observe a call to the method get() on an instance of this class in the call stack of Figure 3 (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 256 515 programs. Consider an attack A using a library l. Suppose that l has n versions. For A, we run 147 × 𝑛 executions. This means that we run each library version on all the 147 JVMs that we have collected. In another case, an attack B can use 𝑛𝑏𝑙𝑖𝑏𝑠 > 1 libraries. Suppose that each library l 𝑖 of them has nbVers[l 𝑖 ] versions. The total number of executions is the sum of all the executions per library involved in the attack i.e., 147

× 𝑛𝑏𝑉 𝑒𝑟𝑠 [𝑙 1 ] + . . . + 147 × 𝑛𝑏𝑉 𝑒𝑟𝑠 [𝑙 𝑖 ] + . . . + 147 × 𝑛𝑏𝑉 𝑒𝑟𝑠 [𝑙 𝑛𝑏𝑙𝑖𝑏𝑠 ]
In other terms, for each attack relying on 𝑛 library (n > 1), we variate one library at once i.e., we fix (𝑛 -1) library versions that are vulnerable in the studied attack and we variate the versions of the remaining library.

Table 1 explains where this 256 515 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 147 × 𝑛 executions, where n defines the number of versions. At the end, we perform 147 × 33 + 147 × 13 + 147 × 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.

Analyzing the results. The results obtained from our experiments are analyzed by:

• 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 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 1 number) or (2) the serialization fails because of "Unsupported major.minor version" (yellow color and V symbol) or (3) the serialization fails because of an "Error while generating or serializing payload" generated by ysoserial (green color andsymbol); • 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.

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 https://github.com/software-engineering-and-security/javadeserialization-rce.

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.

Collecting the CVEs. To collect a suitable set of subject vulnerabilities, we searched specifically for Java deserialization vulnerabilities in the Mitre CVE database 5 , using two queries: {Java, deserialization}, {Java, deserialisation}. We found that there are 104 CVEs.

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:

(1) Deserialization Vulnerability (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 readObject method in the application's code to deserialize his/her untrusted data and carry out the attack). ( 2) GAdget (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. (3) Untrusted Code (UC). A CVE that describes a vulnerability in the deserialization mechanism that can be exploited only if the attacker can execute arbitrary Java code. UC (7.7%) DV (91.3%) GA (1%) As represented in Figure 5, we manually classified 95 (91.3%) of these CVEs as DV, 8 (7.7%) as UC and 1 (∼ 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 5 in Appendix A shows a partial analysis of 29 CVEs for vulnerable Java applications. The complete table with the 104 CVEs is available at https://github.com/software-engineering-andsecurity/java-deserialization-rce.

Experimental Evaluation

In this section, we address the following research questions:

• RQ1: How Frequent are Deserialization Vulnerabilities?

• RQ2: How are Gadgets Introduced?

• RQ3: How are Gadget Libraries Patched?

• RQ4: What is the Life-cycle of Gadgets?

• RQ5: How are Vulnerabilities Patched in Real-life Applications?

• RQ6: How easy is the automation of filters against deserialization attacks?

RQ1: How Frequent are Deserialization Vulnerabilities?

To understand the evolution of reported deserialization vulnerabilities, i.e., vulnerabilities in any programming language for which there is a CVE, as well as the deserialization vulnerabilities specific to Java, we conducted an empirical study based on the Mitre CVE database. Deserialization vulnerabilities are widely spread in many languages. To understand the extent of such vulnerabilities in general, we firstly look for CVEs describing them. A query with the "deserialization" keyword in the Mitre's interface returns 361 CVEs. We checked the alternative "deserialisation" (𝑠 instead of 𝑧) and found four matching CVEs all related to Java vulnerabilities. Out of these four CVEs, one is already present in the first search. In total, we have identified 361 + 4 -1 = 364 deserialization vulnerabilities. The documented deserialization vulnerabilities were reported between 2004 and 2021. Among these, 15 are linked to the Apache commons-collections library (query deserialization, apache, commons, collections).

Note that for searching CVEs in different languages, we need to use very specific keywords separated by space. However, checking the results of our request is relevant to ensure that these results correspond exactly to what we look for. This is because the "results will include CVE Records that match all specified keywords" as mentioned in the search tips of the Mitre website 6 . This means that the results of a request composed of two words "term1 term2" may contain CVEs concerning the vulnerabilities related to term1, those which concern term2, and those for both term1 and term2. The frequency of deserialization vulnerabilities encompassing Java programming language has a notable increase from 2015 until now. Indeed, we found that there are 104 CVEs among which 79 (76%) were reported between 2015 and 2020, see Figure 6.

We looked for further languages such as PHP, XML, and .NET and found that Java is the riskiest language for deserialization attacks among them. Java is one of the most popular and used languages (millions of developers run Java). This may explain why the percentage of (reported) vulnerabilities is higher than the other languages [START_REF]Java: S'informer sur la technologie java[END_REF] [START_REF] Java | [END_REF]. Another point is the spike of vulnerabilities for Java in 2016. This might be related to Frohoff's research and his tool ysoserial. The number of detected vulnerabilities by this tool helps other researchers to use them for detecting new attacks. For example, CVE-2016-2510 describes a gadget in the BeanShell library for which the ysoserial tool presented an exploit called BeanShell1 at the beginning of 2016.

About 40 CVEs related to Java deserialization vulnerabilities have been reported between 2018 and 2020. Most of Java deserialization vulnerabilities are critical because they allow arbitrary code execution on the victim machine. This is probably one of the reasons Java programs and libraries are under scrutiny and so many vulnerabilities have been reported during the last five years. Note that a single gadget may have several reported CVEs. This is caused by the fact that a gadget can be present in many applications and products. Then, a different CVE can be attributed to each application for the same gadget. Unfortunately, this kind of information is often not present in the description of CVEs which prevents us from automatically counting unique deserialization vulnerabilities.

The overall trend shows that the number of CVEs related to deserialization is slightly increasing in the last 10 years. This means that in the real world, serialization is often used in applications to process untrusted data.

RQ2: How are Gadgets

Introduced? To answer this research question, we analyze the results of the experimental protocol described in Section 3.1.1. We consider that a gadget can be introduced in the library(ies) present in the classpath of a victim program and/or in the Java Class Library (JCL), the set of classes shipped with any JVM.

Introducing a gadget in an external library. Our objective is to analyze different attacks in order to show how libraries involved in these attacks include gadgets. Table 2 shows our discoveries about gadget library versions that were not mentioned in the ysoserial repository. The column Discovered version describes all the gadget library versions detected through our experiments. The last column (# of new detected versions) refers to the number of new gadget library versions not including the mentioned ones in ysoserial. For instance, it is mentioned, in this repository, that version 7.7.14 of vaadin-server library contains gadgets. Our experiments have found that 135 more versions contain gadgets.

For each library, we identify its first version containing gadgets and the version just before, i.e., the version before introducing gadgets. We then look at the log of the execution of the victim program using these two libraries, one per execution. The log for the non-gadget library version contains a Java exception which explains the reason for the attack failure. Using this technique, we have identified four surprisingly innocent-looking ways in which gadgets have been introduced: (1) adding a class, (2) adding java.io.Serializable to the list of implemented interfaces, (3) adding a method, and (4) making a class public.

Table 3 shows the studied attacks, the gadget library versions involved in these attacks, their versions without gadgets, and the actions performed to transform a non-gadget library into a gadget one. Among the 19 studied ysoserial exploits, there are five (26%) that are relying on more than one library. These exploits are: CommonsBeanUtils1, Spring1, Spring2, Click1 and Vaadin1.

As shown in Figure 7, there are eight versions (57%) that integrate gadgets by adding a class (keyword AddClass in the figure), three (21.4%) are affected by introducing the interface java.io.Serializable in the list of their implemented interfaces (keyword MakeSerializable in the figure). In the remaining cases, the first one introduces gadgets by changing the status of a class from private to public (7.1%) (keyword ChangeToPublic in the figure) and two library versions introduce gadgets by adding new methods (14.3%) (keyword AddMethods in the figure). These methods are used for the construction of malicious payloads.

In the following, we present two concrete exploits, BeanShell1 and CommonsCollections1, and explain how gadgets have been introduced.

BeanShell1.

The two gadget library versions are beanshell-2.0b4 and beanshell-2.0b5. The version just before 2.0b4 is 2.0b2 and does not contain gadgets. When looking at the content of the log file associated with the execution of the victim program using version 2.0b2, we observe that there is an error when serializing the payload BeanShell1. This error is caused by an illegal access to a class bsh.XThis. We look for this class in the jar file beanshell-2.0b2.jar. We found that this class is defined as private. Now, looking at this class in the gadget version beanshell-2.0b4, we found that its definition has changed to public class bsh.XThis. This makes possible the access to this class, allowing the serialization and thereby the attack.

CommonsCollections1. There are three gadget versions of the library commons-collections: 3.1, 3.2, and 3.2.1 for this attack. For version 3.0, which does not contain gadgets, there is an error while serializing. After analyzing the difference between the versions commons-collections3.0, which does not contain gadgets, and commons-collections3.1, which does contain gadgets, we found that the problem is originating from the class LazyMap. In version 3.0, this class implements only java.util.Map and does not allow the serialization to be performed. In version 3.1, it implements java.util.Map and java.io.Serializable allowing the serialization to succeed.

Detecting a flaw in the JCL. Deserialization vulnerabilities are not only found in Java code from third-party Java libraries but also in Java code from the JCL (Java Class Library) shipped with every JVM. Since this code is always present in all JVMs, we discuss it in more detail here. In our experiments, and for a studied attack, we vary the JVM versions in order to check if the attack succeeds or not for a gadget library version. Our goal is to identify the flaw in the Java Runtime Library (JRL) that allows the execution of such an attack. We then filter the results and distinguish three types of flaws allowing the insecure deserialization: (1) adding a readObject() method to a class of the JCL. This class can be used in the code to generate a malicious byte stream (example: the BadAttributeValueExpException class); (2) change the type of some fields to make them accessible and easily controlled by the attacker; (3) change the bytecode within a catch block.

Illustration

Consider the method readObject() of the class AnnotationInvocationHandler in the two JDK-versions jdk1.7.0.21 and jdk1.7.0.25, shown in Figure 8. When analyzing the two code snippets, it is important to note that the field this.type (used in line 7) might be attacker-controlled. The first readObject in jdk1.7.0.21 allows the deserialization attack because the catch block fails silently: it uses the instruction return; (line 10 of Figure 8a) which will exit the readObject and let the attack continue. The readObject in jdk1.7.0.25 prevents the attack because the catch throws an InvalidObjectException displaying a message "Non-annotation type in annotation serial stream". Even though the second version of readObject does not allow the attack, an analysis of the try block content i.e., the calls inside the getInstance() method, would be necessary to check for the presence of method calls that may invoke gadgets. Java deserialization gadgets are not only introduced by adding new classes (8 out of 14 libraries (57%) added classes). As code evolves, methods are updated or added, class signatures can change (43% of the 14 libraries comprise such changes). Thus, small code changes which look innocuous can frequently introduce gadgets.

RQ3:

How are Gadget Libraries Patched? Table 4 shows the actions performed to fix flaws in the studied gadget libraries. Note that the different patches present in this table can be either with the purpose of mitigating a gadget or a coincidental fix due to some changes for other purposes. In order to classify commits mitigating gadgets, we manually analyzed their messages. The result is represented in the last column of this table: when the action aims at fixing the gadget against deserialization, we mention it by "Y"; when it is a coincidental fix we put "N"; when the library is not patched, we use "-"; and when we do not find information about if the patch is intentional or coincidental we put the "Unknown" keyword. In this table, the second column represents the number of gadgets that we extract from each attack. This number ranges from a minimum of 7 gadgets for the CommonsCollections1 attack to a maximum of 19 gadgets for the BeanShell1 attack. To find the corresponding patch in a library, we study the last version containing gadgets and the version just after, which is gadget-free. In this table, and as presented in Figure 9, a gadget patch may consist in:

RemoveSerializable removing the java.io.Serializable from the list of interfaces implemented by the vulnerable class. This action represents 12.5% of cases, RemoveClass removing the vulnerable class in 18.75% of cases, IntroduceCheck introducing a safety check to disable insecure serialization. This safety check can be an instruction in the code of a method or a whole added check method in 18.75% of cases, ChangeSignature changing the signature of a method in 6.25% of cases, or RemovePackage removing a package from the gadget library (case of clojure) representing Let us now analyze two different actions performed to fix the attacks BeanShell1 -described in Section 3.2.2 -and CommonsBeanUtils1. The patch of the libraries involved in these two attacks is described in Table 4.

BeanShell1. This gadget library is patched in the version beanshell-2.0b6 by removing java.io.Serializable from the list of interfaces implemented by the class XThis$Handler. As a result, this class can no longer be serialized.

CommonsBeanUtils. First, note that this attack uses gadgets in two libraries: commons-beanutils and commons-collections. We found that the gadget library commons-beanutils was never patched. For the commons-collections library, the gadget is patched by removing the ComparableComparator class.

Once a class is in a library, removing it might break backward compatibility, thus this removal is not often an option. Among the studied patches, 18.75% remove a class and 18.75% add a check. Other solutions include adding a safety check to disable the insecure deserialization, removing the java.io.Serializable interface from the list of implemented interfaces or even removing a whole library package. A significant number of cases (37.5%) are not patched at all.

RQ4: What is the Life-cycle of Gadgets?

To define the life-cycle of a gadget library or a gadget library version, we extract the following dates:

• when the first library version has appeared, i.e., the jar file appearance date,

• when the gadget was introduced, and • when the library was patched. We look either at the appearance date of the released version free from gadgets or at the date of the patch in CVE if it exists.

Figure 10 shows the answers to this RQ according to the different studied attacks. In this figure, each line represents the life-cycle of a library for which we distinguish between: (1) the versions before the known gadgets were introduced (uncolored rectangle); (2) the versions that contain gadgets (dashed rectangle); and (3) the patched versions of the gadget library (black rectangle). First of all, note that the libraries spring-beans, spring-core, spring-aop, and vaadin-server have several versions developed in parallel. Each one of these versions is described by a line in the figure.

According to Figure 10, we observe that most of the studied attacks are detected late. In fact, for some libraries like groovy and js-rhino, the detection of the gadgets takes 7 years. This can be explained by the fact that the ysoserial tool has been developed in 2016 and the introduced vulnerabilities use versions of libraries that were developed from the beginning of the 2000s. We also observe that most of the libraries take between two months and several years to be patched. The longest time is for the commons-collections and bsh libraries and is equal to eleven years. The shortest time is two months for the library spring-aop-1. Furthermore, we have classified the studied (versions of) libraries into three categories: Cat1 (versions of) libraries for which gadgets were introduced and then patched. This category contains the groovy, js-rhino, commons-collections, bsh, clojure, and spring-aop-1 libraries. Cat2 libraries which are never patched, like the commons-beanutils, rome, spring-beans, vaadinserver-7, vaadin-shared, click-nodeps, and javax-servlet libraries. Cat3 library versions that contain gadgets from their appearance date. We cite as examples the vaadin-server-7, spring-aop-3, spring-aop-4, spring-beans-3, spring-beans-4, and springbeans-5. Observe that the presentation of the spring-core-4 library is simplified in the Merging all these branches in spring-core-4 would have resulted in a "contains gadget" "patched" "contains gadget" "patched" pattern which is wrong since it suggest the gadgets are reintroduced.

To simplify the figure, we represent spring-core-4 as being patched when the first branch is patched and ignore the fact that there is a delay to propagate this patch to other branches. Note that our study about the patching time of gadgets does not aim to advocate fixing patches so quickly. Rather than that, our goal is to give an observation about the time that is taken to patch existing gadgets.

When introducing gadgets in a library, the latter can be patched in few months. However, for some libraries, the patch is applied after several years going until more than 10 years.

RQ5: How are Vulnerabilities Patched in Real-life Applications?

For this study, we use the 95 CVEs describing Java deserialization vulnerabilities we have identified in Section 3.2.1 (see Figure 5). We manually analyzed their corresponding 77 applications containing the vulnerabilities to understand what has been changed in these applications to prevent the exploitation of these vulnerabilities.

We observe that 69 applications (89.6%) have a single CVE, yet that eight applications (10.4%) have multiple reported CVEs. For example, the Atlassian Bamboo before 5.9.9 and 5.10.x before 5.10.0 application had two CVEs in two years: First CVE-2014-9757, for which the fix consists in upgrading the Smack library used by the Bamboo application. Unfortunately, this fix does not prevent the next vulnerability, CVE-2015-8360. The fix for this second CVE is a patch that introduces both allow and deny lists. Thus, even though a fix exists, it may be not sufficient to protect the application from future attacks. Among all the 95 CVEs associated with the 77 studied applications, we successfully analyzed 58 CVEs based on: the CVE description (41 CVEs), the code of the impacted application (6 CVEs), or the workaround description (11 CVEs). We were unable to analyze 37 CVEs either because the code of the applications is not publicly available (neither source nor bytecode, for 36 CVEs) or because our manual analysis exceeded a time limit (1 CVE). A description of 29 CVEs among the 95 CVEs is available in Table 5 of Appendix A.

In total, we were able to analyze 58 CVEs from 52 applications. Figure 11 presents the different categories of patches and mitigation techniques software vendors have devised. Among the 58 solutions, eleven (19%) disable (de)serialization functionalities (e.g., CVE-2020-11973); eleven (19%) add an allow list containing the list of allowed classes or packages to use deserialization (e.g., CVE-2013-2165); ten (17.2%) add a deny list in which the classes are not allowed to be deserialized (example of CVE-2018-20732); eight (13.8%) add checks in serializable classes (keyword AddChecks in the figure) which may go from adding some instructions (e.g., CVE-2016-6793) to activating the sandbox (e.g., CVE-2018-1000058); seven (12%) upgrade library versions (e.g., CVE-2014-9757); four (6.9%) protect or restrict access to ports (e.g., CVE-2017-10934); three (5.2%) disable protocols (e.g., CVE-2015-4852); three (5.2%) do nothing because the application software reaches the end of life (e.g., CVE-2016-7065); one (1.7%) changes the software configuration (CVE-2020-9493).

Note that for 13 CVEs there is no patch (i.e., the code is unmodified) but only a workaround solution. Such methods consist mainly in blocking access to the vulnerable code in order to reduce the severity of the impact of the attack or to prevent it. They do not modify the vulnerable code itself but work around this code to prohibit the access for performing the attack. For instance, the solution to mitigate CVE-2018-15381 consists in blocking or protecting the access to a port. Obviously, this does not remove the vulnerability in the application in question. In other words, the application is still exposed to the risk of attacks if, for some reason, the access to the port becomes allowed again (e.g., new software configuration, software deployed in a new environment). We complete our analysis by the study the nature of commits patching deserialization vulnerabilities: are these patches manual code modifications or are they automatically generated by a tool? To have access to commits/patches, the applications must be open-source. Thus, we selected 25 open-source vulnerable applications which use deserialization. Among these 25 applications, listed in Table 8, we found 17 applications having code patches that were manually generated and described in commits. The remaining seven applications either update an external dependency (4), are end-of-life (1) or we were unable to find the patch [START_REF] Balzarotti | Saner: Composing Static and Dynamic Analysis to Validate Sanitization in Web Applications[END_REF]. We observe that no commit is classified as being generated by a tool. The results of our analysis are described in Table 8 of Appendix C. Deserialization vulnerabilities may be present on several occasions for the same application. Disabling the deserialization in Java applications and building an allow-list are the most popular kinds of patches for this kind of attacks (19% of cases for each one of these actions). Such patches may prevent deserialization attacks once and for all. However, for some applications, the patching/mitigation action consists in upgrading library versions (12% of cases), which is not safe since the attacker could find another way to carry out the attack. All patches in the open-source applications we have analyzed were manually written which may suggest that tools are rarely used to automatically fix this kind of vulnerability.

RQ6:

How easy is the automation of filters against deserialization attacks? Since 2016, Java supports a filtering mechanism to prevent the exploitation of deserialization vulnerabilities. This filter, described in JEP 290 [START_REF] Broujerdi | Jdk approach to address deserialization vulnerability[END_REF][START_REF]Jep 290: Filter incoming serialization data[END_REF], can restrict classes to be deserialized to a specific set (allow list) or prevent a specific set of classes from being deserialized (deny list).

To use these filters, we have to extract classes used by Java applications to either: (1) create a deny list containing at least one class from each deserialization attack (in order to prevent each attack) and make sure that the deny list will not break any Java application or (2) create an allow list containing all classes used by the Java application during deserialization and make sure that it prevents all the attacks. To be able to create these allow and deny lists, we first extract the set of classes required by the 19 ysoserial deserialization attacks. These classes are listed in Table 6. We then manually extract the set of classes used during deserialization from 10 real-world vulnerable applications which use deserialization. This set is listed in Table 7.

Unfortunately, we observe that all the Java applications make use of generic types such as ArrayList<Object> or Serializable. This is problematic since the allow list should then contain all possible serializable classes and the deny list should then be empty which makes the filters useless. This shows that an analysis of the code deserializing data is not precise enough to generate a useful set of classes that can be used in filters. There are two solutions that can be explored as future work. The first is to rely on the in-depth knowledge of the applications by the developers themselves. However, in practice, it might be difficult for the following reasons: contacting the developer responsible for the code might not be possible because the person might have left the project; the developer might not remember precisely how the code works, etc. The second is to automate the analysis of the applications to automatically extract the set of classes used by the application. While at a first sight this approach seems to work, it will face the challenges of static analysis such as reflection, code loading, and other language-specific features difficult to analyse automatically.

Furthermore, as the code of applications evolves, the allow/deny lists must be kept synchronized with the new versions. This would require that developers spend time debugging and updating these lists instead of working on the application's code directly.

In the lab, deserialization attacks can be trivially blocked when activating the filter. However, in practice setting up and maintaining these filters suppose that developers know in advance the types to deserialize in the application which, often, is not trivial because of technical limitations, time constraints, or project management challenges.

Synthesis and Take-away Messages

Our work has yielded the following important conclusions: (1) the persistent deserialization of untrusted data; [START_REF] Balzarotti | Saner: Composing Static and Dynamic Analysis to Validate Sanitization in Web Applications[END_REF] what is the effect of disabling the java.io.Serializable in the patches; [START_REF] Bartel | Musti: Dynamic Prevention of Invalid Object Initialization Attacks[END_REF] what are the factors impacting the duration of finding a patch; (4) how precise is the definition of deserialization vulnerabilities in CVEs description; and [START_REF] Bloor | Deserlab[END_REF] what are the take-away messages from our analysis results.

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. " [START_REF]OWASP: A8:2017-insecure deserialization[END_REF] [START_REF] Security | Insecure deserialization: Owasp top 10 -a8[END_REF]. 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" [START_REF]Oracle: Secure coding guidelines for java se[END_REF]. 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.

Disable Serializable

When analyzing the gadget patches (see Table 4), we find that disabling the deserialization, by removing the 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.

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.

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).

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 3. When a developer introduces a new class that can be serialized or modifies an existing one (see Table 3 for real-world examples), we suggest the following recommendations:

• List all the new field types and sub-types which are introduced or modified.

• For each type, check that there is no code reachable from the 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).

5 Limitations

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 3 is not exhaustive. These actions are extracted from the 19 exploits described in ysoserial.

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 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.

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 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-268587 a .NET deserialization vulnerability used by the HAFNIUM group to run code as SYSTEM on Microsoft Exchange servers [START_REF] Mstic) | Hafnium targeting exchange servers with 0-day exploits[END_REF]: 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.

6 Related work

Deserialization vulnerabilities

Preventing deserialization attacks starts right at the serialization step. As explained in [START_REF] Lawrence | Best practices for java security[END_REF], 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 et al. [START_REF] Koutroumpouchos | Objectmap: detecting insecure object deserialization[END_REF] have developed a dynamic tool called 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 et al. [START_REF] Frohoff | ysoserial[END_REF] have implemented the ysoserial tool which provides 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 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 Gadget Inspector [START_REF] Haken | Gadget inspector[END_REF] 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 SerializationDumper [START_REF] Bloor | Serializationdumper[END_REF] 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 DeserLab [START_REF] Bloor | Deserlab[END_REF], a Java client and server application that implements a custom network protocol using the Java serialization format to demonstrate Java deserialization vulnerabilities.

Rasheed et al. [START_REF] Rasheed | A Hybrid Analysis to Detect Java Serialisation Vulnerabilities[END_REF] 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 [START_REF] Fingann | Java deserialization vulnerabilities exploitation techniques and mitigations[END_REF] 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 [START_REF] Waratek | The deserialization problem[END_REF], the tools like ysoserial [START_REF] Frohoff | ysoserial[END_REF] and Gadget Inspector [START_REF] Haken | Gadget inspector[END_REF], the deserialization gadgets and chains of gadgets [START_REF] Daconta | When runtime.exec() won't[END_REF], and the code practices to prevent deserialization attacks [START_REF]Prevent deserialization of untrusted data[END_REF][START_REF] Schneider | Java deserialization security faq[END_REF].

Combating the deserialization attacks is one of the ideas explored by Seacord who examines in [START_REF] Seacord | Combating java deserialization vulnerabilities with look-ahead object input streams[END_REF] Java deserialization vulnerabilities and evaluates various look-ahead object input streams solutions. Cristalli et al. [START_REF] Cristalli | Trusted Execution Path for Protecting Java Applications Against Deserialization of Untrusted Data[END_REF] 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: "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" [START_REF] Cristalli | Trusted Execution Path for Protecting Java Applications Against Deserialization of Untrusted Data[END_REF].

Deserialization vulnerabilities are not limited to the Java language. Shahriar et al. [START_REF] Shahriar | Object injection vulnerability discovery based on latent semantic indexing[END_REF] 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 [START_REF] Manning | Introduction to information retrieval[END_REF]) 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 et al. [START_REF] Dietrich | Evil Pickles: DoS Attacks Based on Object-Graph Engineering[END_REF] 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 et al. [START_REF] Peles | One Class to Rule Them All: 0-Day Deserialization Vulnerabilities in Android[END_REF] 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 et al. [START_REF] Alexopoulos | The Tip of the Iceberg: On the Merits of Finding Security Bugs[END_REF] presented a detailed analysis of the large body of open-source software packaged in the popular Debian GNU/Linux distribution. Vasquez et al. [START_REF] Vásquez | An empirical study on android-related vulnerabilities[END_REF] 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 et al. [START_REF] Mazuera-Rozo | The android OS stack and its vulnerabilities: an empirical study[END_REF] 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. [START_REF] Fingann | Java deserialization vulnerabilities exploitation techniques and mitigations[END_REF][START_REF] Muñoz | Friday the 13th json attacks[END_REF] show that attackers may be able to perform their attacks regardless of the malicious data format. XMLEncoder/XMLDecoder [START_REF]Oracle: Long term persistence[END_REF] 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 [START_REF] Hat | Java deserialization flaws: Part 2, xml deserialization[END_REF]. The use of these alternative serialization mechanisms is not necessarily an effective solution to prevent deserialization attacks. In fact, Fingann [START_REF] Fingann | Java deserialization vulnerabilities exploitation techniques and mitigations[END_REF] 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 [START_REF] Software | Kyro[END_REF] is an alternative Java implementation for serialization. Similarly to the native Java implementation [START_REF] Riggs | Pickling state in the java system[END_REF], it can lead to arbitrary code execution [START_REF] Database | Vulnerability summary for cve-2020-5413[END_REF].

ProtocolBuffers [START_REF]Google: Protocol buffers[END_REF] 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 java.lang.reflect.Method. On top of that, the ProtocolBuffers' Java implementation itself was vulnerable to a denial of service attack [START_REF] Database | Vulnerability summary for cve-2021-22569[END_REF].

Java deserialization filtering is the technique supported by Oracle [START_REF]Oracle: Core libraries -serialization filtering[END_REF]. 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.

Java Security

Balzarotti et al. [START_REF] Balzarotti | Saner: Composing Static and Dynamic Analysis to Validate Sanitization in Web Applications[END_REF] 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 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 [START_REF] Holzinger | An In-Depth Study of More Than Ten Years of Java Exploitation[END_REF]. These attacks lead to security vulnerabilities that involve issues such as type confusion, deserialization issues, trusted method chaining, or confused deputies. Holzinger et al. [START_REF] Holzinger | An In-Depth Study of More Than Ten Years of Java Exploitation[END_REF] 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 et al. [START_REF] Chen | Deep differential testing of JVM implementations[END_REF] dealt with the problem of validating the production of JVMs. The 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 classming in the same context of validating JVMs. Their method is based on a technique called 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 [START_REF] Bonnaventure | Confuzzion : A java virtual machine fuzzer for type confusion vulnerabilities[END_REF] 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 et al. [START_REF] Dean | Java security: From hotjava to netscape and beyond[END_REF] 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 et al. [START_REF] Holzinger | Hardening java's access control by abolishing implicit privilege elevation[END_REF] 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 securitypreserving 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 et al. [START_REF] Bartel | Musti: Dynamic Prevention of Invalid Object Initialization Attacks[END_REF] presented an approach based on a runtime solution called 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 et al. [START_REF] Chisnall | Cheri jni: Sinking the java security model into the c[END_REF] 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.

Conclusion

The Java language is one of the most used languages to develop applications. Thanks to its ease of use and its portability, millions of applications run using this language. However, every year, many vulnerabilities in the Java runtime and its runtime libraries are discovered, reported, and patched. Our work highlights that vulnerabilities such as Java deserialization vulnerabilities can be critical since they impact the security of the applications, and in most cases allow the execution of arbitrary code. In this paper, we have performed 256 515 experiments on 19 RCE deserialization attacks. We have identified that not only the mentioned library versions in ysoserial attacks contain gadgets, but that there are previous and later versions that contain these gadgets as well. As an example, it is mentioned in this repository that the version 1.9.2 of the commons-beanutils library includes gadgets. After running our experiments, we found that 14 more versions contain also the same gadgets. These versions belong to the range between 1.5 and 1.9.4. We have studied how gadgets are introduced in libraries and observe that the modification of one innocent-looking detail in a class -such as making it public -can already introduce a gadget. Defense mechanisms such as filtering and allow/deny listing might be effective in preventing such attacks but might be hard to set up and maintain. We have performed an analysis of 104 CVEs -associated with vulnerable Java applications -from the Mitre database. We discovered that the results of our search on Mitre contain noise that we need to remove: among these 104 CVEs, only 95 CVEs represent "real" deserialization vulnerabilities description. The remaining 9 CVEs represent other types that we classified into GA (gadgets description) and UC (untrusted code description). We find that some patches of these application-level vulnerabilities consist in upgrading library dependencies although these are frequently insufficient to prevent the deserialization attacks. Among the 95 studied CVEs, we were able to analyze 58 CVEs in which 19% are correctly fixed by disabling the deserialization of untrusted data.

A perspective for future work is the development of an algorithm for automatically detecting deserialization gadgets chains in applications, evaluate this implementation on a set of applications and compare it with other existing tools such as Gadget Inspector [START_REF] Haken | Gadget inspector[END_REF]. Our goal is to prevent deserialization attacks early. Identifying the parameters involved to define the duration of patching libraries is another perspective of this work. In this paper, we have focused only on RCE attacks since we have designed a framework to test only this kind of attacks. Now, we are planning an extension of this framework to cover the remaning 15 non-RCE ysoserial attacks containing DOS ones which aim at making services unavailable to their legitimate users. The extension uses a socket connection to send serialized Java objects. Deserialization is not restricted to an allow-list, thus allowing an attacker to achieve code execution via a malicious deserialization gadget chain. The socket is not bound exclusively to localhost. The port this socket is assigned to is randomly selected and is not intentionally exposed to the public (either by design or documentation). This could potentially be used to achieve remote code execution and local privilege escalation. ) or the code of the libraries used in the concerned application (External). The fifth column "Automatically/manually generated patch?" indicates if the patch was manually generated or automatically generated by tools like Snyk [START_REF]GitBook: Introducing snyk[END_REF][START_REF] Snyk | Snyk cli[END_REF]. For each existing patch, we give the link to the commit in which is described the patch. For the applications for which we do not find commit for patch, we use the keyword "Unknown" in the last column. For the applications that do not have a patch, we put the "-" symbol.

7 } 8 private 11 }Fig. 1 .

 78111 Fig.1. A simple example of a serializable class. In this class, the attacker can modify the command field. Thus, during deserialization, when the JVM calls A.readObject() method, the attacker command will be executed instead of "top".

20 } 21 } 1 / 2 JVM 9 / 14 } 15 }

 20211291415 (a) A vulnerable class. (This sub-figure is a modified version of Figure 1.) * libA.jar is in the classpath of the / if the attacker gives an object of type 'A' 10 // to deserialize, A.readObject is executed 11 // before the cast to (String) 12 String s = (String) ois.readObject(); 13 ois.close(); (b) A class deserializing an input file.

Fig. 2 .

 2 Fig. 2. Explanatory example for the terminology.

Fig. 3 .

 3 Fig. 3. Abstraction of call stack of the CommonsCollections1 attack.

Fig. 4 .

 4 Fig. 4. Components of the serialized byte stream generated by the ysoserial tool and which will be deserialized by the victim class in Figure 2b.

Fig. 5 .

 5 Fig. 5. More than 91% of CVEs found via a search with keywords 'Java' and 'deseriali[sz]ation' represent real Java deserialization vulnerabilities.

Fig. 6 .

 6 Fig. 6. Frequency of deserialization reported CVEs between 2010 and June 2021 according the MITRE database.

1 private 15 }Fig. 8 .

 1158 Fig. 8. Two versions of AnnotationInvocationHandler.readObject().

Fig. 10 .

 10 Fig. 10. Life-cycle of some library versions.

Figure 10 .

 10 Indeed, this version contains four branches: 4.0.* . . . 4.1.* . . . 4.2.* and 4.3.* which are developed in parallel. The gadgets were initially patched in one branch and, a few months later, ported to other branches.

EndOfLife ( 5 Fig. 11 .

 511 Fig. 11. Patching/Mitigation actions for the 58 CVEs.

Table 1 .

 1 Studied attacks and the number of experiments per attack

	Attack name	Lib name	# lib versions # experiments per lib # experiments per attack	Total
	BeanShell1	beanshell	16	147 x 16 = 2352	2352
	Clojure	clojure	145	147 x 145 = 21315	21315
		commons-beanutils	33	147 x 33 = 4851
	CommonsBeanUtils1	commons-collections 13	147 x 13 = 1911	4851 + 1911 + = 8232
		commons-logging	10	147 x 10 = 1470
	CommonsCollections1 commons-collections 13	147 x 13 = 1911	1911
	CommonsCollections2 commons-collections 13	147 x 13 = 1911	1911
	CommonsCollections3 commons-collections 13	147 x 13 = 1911	1911
	CommonsCollections4 commons-collections 13	147 x 13 = 1911	1911
	CommonsCollections5 commons-collections 13	147 x 13 = 1911	1911
	CommonsCollections6 commons-collections 13	147 x 13 = 1911	1911
	CommonsCollections7 commons-collections 13	147 x 13 = 1911	1911
	Groovy1	groovy	192	147 x 192 = 28224	28224
	ROME	rome	12	147 x 12 = 1764	1764	256515
	MozillaRhino1	js-rhino	26	147 x 26 = 3822	3822
	MozillaRhino2	js-rhino	26	147 x 26 = 3822	3822
	Spring1	spring-beans spring-core	180 186	147 x 180 = 26460 147 x 186 = 27342	26460 + = 53802
		spring-core	186	147 x 186 = 27342
	Spring2	aopalliance commons-logging	2 10	147 x 2 = 294 147 x 10 = 1470	27342 + 294 + + 27930 = 57036
		spring-aop	190	147 x 190 = 27930
	Click1	click-nodeps javax-servlet	8 20	147 x 8 = 1176 147 x 20 = 2940	1176 + 2940 =
	Vaadin1	vaadin-server vaadin-shared	199 199	147 x 199 = 29253 147 x 199 = 29253	29253 + = 58506
	JDK7U21		147	147 x 1 = 147	147

Table 2 .

 2 Discovered versions of gadget libraries using our experiments

	Library name	Version mentioned in	Discovered versions	# of new detected ver-
		ysoserial		sions
	beanshell	2.0b5	2.0b4 and 2.0b5	1
	clojure	1.8.0	1.6.0-beta1 until 1.9.0-alpha15	46
	commons-beanutils	1.9.2	1.5 until 1.9.4	14
	commons-collections	3.1 and 4.4.0	2.1.1, 3.0, 3.1, 3.2, 3.2.1, 3.2.2, 4.4.0-alpha1 and 4.4.0 6
	groovy	2.3.9	2.3.0-beta-2 until 2.4.3	25
	rome	1.0	0.5 until 1.0	7
	js-rhino	1.7R2	1.6R6, 1.6R7, 1.7R2 until 1.7.7	9
	spring-beans	4.1.4.RELEASE	3.0.0.RELEASE until 5.2.9.RELEASE	140
	spring-core	4.1.4.RELEASE	4.0.0.RELEASE until 4.2.2.RELEASE	21
	spring-aop	4.1.4.RELEASE	1.1-rc1, 1.1-rc2, 1.1, 3.0.0 until 4.2.9	64
	click-nodeps	2.3.0	2.1.0-RC1-incubating until 2.3.0	6
	javax.servlet	3.1.0	3.0.1 until 4.0.1	19
	vaadin-server	7.7.14	7.0.0.beta1 until 7.7.17	135
	vaadin-shared	7.7.14	7.4.0.beta1 until 8.11.3	122

Table 3 .

 3 Actions performed to introduce a gadget in a library Fig.7. In more than 57% of the 14 studied libraries, gadgets are introduced by adding a class.

	Attack name	Gadget-free version	First gadgets version	Introducing gadgets action
	BeanShell1	beanshell-2.0b2	beanshell-2.0b4	Change private class bsh.XThis to public
	Clojure	clojure-1.6.0-alpha3	clojure-1.6.0-beta1	Add a class AbstractTableModel$ff19274a
	CommonsBeanUtils1	commons-beanutils-1.4.1	commons-beanutils-1.5 Add a class BeanComparator that implements Serializable
		commons-collections (2001) commons-	Add a class ComparableComparator
			collections2.1.1
	CommonsCollections1, 3	commons-collections3.0	commons-collections3.1 Add implements Serializable to the class LazyMap
	and 7
	CommonsCollections2	commons-collections3.2.2	commons-collections4-	Add a class TransformingComparator to the library
	and 4		4.0-alpha1
	CommonsCollections5	commons-collections3.0	commons-collections3.1 Add implements	Serializable to the class
	and 6			TiedMapEntry
	Groovy1	groovy-2.3.0-beta1	groovy-2.3.0-beta2	Add a class Opcodes
	ROME	rome-0.4	rome-0.5	Add a class ObjectBean
	MozillaRhino1 and 2	js-rhino-1.6R5	js-rhino-1.6R6	Add a private method accessSlot() in the class
				ScriptableObject
		spring-beans-2.5.6.SEC01	spring-beans-	Add a class ObjectFactoryDelegatingInvocation-
	Spring1 and 2		3.0.0.RELEASE	Handle which implements Serializable
		spring-core-3.2.5.RELEASE	spring-core-	Add a class SerializableTypeWrapper$MethodInvoke-
			4.0.0.RELEASE	TypeProvider
		spring-aop-1.0-rc1	spring-aop-1.1-rc1	Add implements	Serializable to the class
				JdkDynamicAopProxy
	Click1	click-nodeps2.0.1-incubating click-nodeps2.1.0	Add implements ColumnComparator	Serializable to the class
		javax-servlet	vulnerable from its first	-
			release
	Vaadin1	vaadin-server	release vulnerable from its first	-
		vaadin-shared-7.4.0-alpha14 vaadin-shared-7.4.0-	Add a method Capitalize(String) in the class
			beta1	SharedUtil
	JDK7U21	jdk1.7.0.25	jdk1.6.0.04	-
		Add a class (57%)
				Add methods (14.3%)
	Make a class serializable (21.4%)	Change private class to public (7.1%)

Table 4 .

 4 We have noticed that, in the 14 studied libraries, only 8 of them are patched. We have identified 11 patching actions in this table. The remaining 6 libraries over 14 (37.5%) are not patched (NotPatched keyword in the figure). Different actions to fix a flaw in libraries

	6.25% of cases.
	RemoveClass (18.75%)
	IntroduceCheck (18.75%)
	RemoveSerializable (12.5%)
	ChangeSignature (6.25%)
	RemovePackage (6.25%)
	NotPatched (37.5%)

Fig. 9. Actions performed to remove gadgets from libraries.

  IBM Maximo Asset Management could allow a remote authenticated attacker to execute arbitrary code on the system, caused by an unsafe deserialization in Java. By sending speciallycrafted request, an attacker could exploit this vulnerability to execute arbitrary code on the system Inaccessible patch (when connecting to https: //www.ibm.com/support/pages/node/6332587 an error message ("No applicable IBM support agreement found for one or more of the products you selected") appears) is present in Taoensso Nippy before 2.14.2. In some circumstances, it is possible for an attacker to create a malicious payload that, when deserialized, will allow arbitrary code to be executed. This occurs because there is automatic use of the Java Serializable interface: Nippy introduced a feature to allow the automatic use of Java's Serializable interface as a fallback for types that Nippy didn't support via its own Freezable protocol.Use a predicate (fn allow-class? [class-name])fn that can be assigned to '*freeze-serializable-allowlist*' and/or '*thaw-serializable-allowlist*'. This predicate is used to record information about which classes have been using Nippy's Serializable support in the user's environment (see http://ptaoussanis.github.io/nippy/ taoensso.nippy.html#var-allow-and-recordany-serializable-class-unsafe) Apache Tapestry 4 will attempt to deserialize the "sp" parameter even before invoking the page's validate method, leading to deserialization without authentication Apache Tapestry 4 reached end of life in 2008 and no update to address this issue is released (the upgrade to the latest Apache Tapestry 5 version is necessary) (see https://lists.apache.org/thread.html/r700a-

	VMware vReal-SolarWinds Vir-Apache Ofbiz OpenNMS Hori-Taoensso Nippy	CVE-2015-CVE-2016-CVE-2019-CVE-2020-CVE-2020-	https://docs.vmware.com/ No https://archive.apache.org/dist/ https://github.com/OpenNMS/ https://github.com/	Remote attackers can execute arbitrary The vulnerability exists due to the de-This issue is exposed by the The ActiveMQ channel configuration A deserialization flaw X Replace the Commons collections library by X Inaccessible patch (it is mentioned that there is a X Improve ObjectInputStream class X Remove a parameter after stopping the X
	ize Orchestrator tualization Man-from 16.11.01 to zon < 26.0.1 < 2.14.2	6934 3642 0189 12760 24164	en/vRealize-Orchestrator/ ofbiz/ opennms/releases/tag/ ptaoussanis/nippy	commands via a crafted serialized Java serialization of untrusted data in the "webtools/control/httpService" allowed for arbitrary deserialization of	the commons-collections-3.2.2.jar in the depen-hotfix in https://packetstormsecurity.com/ and redefine it as a new class use of serialized object messages in a
	6.x, ager <= 6.3.1 vCenter 16.11.05 and Meridian		7.6/rn/VMware-vRealize-opennms-26.0.1-1	object, related to the Apache Com-RMI service running on port 1099/TCP. URL, and uses Java deserialization Java objects leading to remote code ex-	dencies of the mentioned products (see https: files/137486/Solarwinds-Virtualization-SafeObjectInputStream in which there is file applicationContext-daemon.xml:
	Orchestrator before 2018.1.19		Orchestrator-76-Release-	mons Collections library A remote attacker can execute operat-to perform code execution. In the ecution for any authenticated channel	//kb.vmware.com/s/article/2141244 and https:// Manager-6.3.1-Java-Deserialization.html an added whitelist. Also add objects from <property name="trustAllPackages"
	5.x, and 2019 before vRealize		Notes.html	ing system commands as an unprivi-HttpEngine, the value of the request user regardless of its assigned permis-	kb.vmware.com/s/article/2141244) and https://seclists.org/fulldisclosure/2016/Jun/29 org.apache.commons.fileupload (namely value="true"/> (see https://github.com/
	Operations 2019.1.7				leged user 8 parameter serviceContext is passed sions	but no more details are given) DiskFileItem and FileItemHeadersImpl) OpenNMS/opennms/pull/2983 and https://
	6.x, HP	vCenter Network	CVE-2016-	No	A vulnerability in Apache Commons to the deserialize method of	Unknown patch as non-serializable github.com/OpenNMS/opennms/pull/2983/files/ in this class	X
	Operations 5.x, Node Manager	4398		Collections for handling Java object XmlSerializer.	SafeObjectInputStream (see the diff be-e21fc14ce355533493da0db815bd81a66e291382)
	and i (HP-NNMi) vCenter			deserialization was addressed by HPE	tween the two versions 16.11.05 and 16.11.06. See https://github.com/davidhalter/parso/issues/
	Application Software 10.00,			Network Node Manager i (NNMi) Soft-	also https://gitbox.apache.org/repos/asf?p=of-75#)
	Discovery Man-10.01 (patch1), IBM Maximo	CVE-2020-	https://github.com/nishi2go/	ware. The vulnerability could be re-	biz-framework.git;a=blob;f=framework/ba-	X
	ager (vADM) 10.01 (patch 2), Asset Manage-	4521	maximo-docker	motely exploited to allow remote code	se/src/main/java/org/apache/ofbiz/base/-
	7.x 10.10 ment 7.6.0 and			execution.	util/SafeObjectInputStream.java;h=d50cf-
	Adobe Experi-Apache Wicket 7.6.1 Apache	CVE-2016-CVE-2016-CVE-2020-	No https://archive.apache.org/dist/ https://github.com/apache/	Adobe Experience Manager 5.6.1, 6.0.0, The DiskFileItem class in Apache	Unknown patch Change the bf11fc4d3b5855c53cb38a6cde7e101dc83;h-class DiskFileItem:	X X X
	ence Manager 6.x < 6.25.0 and Tapestry	0958 6793 17531	wicket/ tapestry4	and 6.1.0 might allow remote attackers Wicket allows remote attackers	add b=3f60efb)	a	check	instruction
	(Adobe-EM) 1.5.x < 1.5.17 Apache 4	CVE-2019-	https://downloads.apache.org/	to have an unspecified impact via a to cause a denial of service (infi-Manipulating classpath asset file	Files.checkFileName(tempDir.getPath()) The fix for that bug was a blacklist filter	X
	5.6.1, 6.0.0, and Tapestry	0195	tapestry/	crafted serialized Java object. nite loop) and write to, move, and URLs, an attacker could guess the path	in the method getTempFile() of the patched that checks if the URL ends with '.class',
	6.1.0					delete files with the permissions of to a known file in the classpath and	version (patch obtained by doing the diff betwwen '.properties' or '.xml'. However, it is
	Hazelcast Cisco Security <	CVE-2016-CVE-2020-	https://github.com/hazelcast/ No	A flaw was found in the cluster join DiskFileItem, and if running on a have it downloaded. It is possible to Multiple vulnerabilities in the Java de-	Add class names blacklisting and whitelisting the 6.24.0 and 6.25.0 versions) proven that this blacklist solution can sim-Unknown patch 6aa234dbff0555d4187bdc8274d7e4c0afbf35b9-	X X
	3.11 Manager (Cisco-	10750 27131	hazelcast	procedure in Hazelcast. This flaw al-Java VM before 1.3.1, execute arbitrary download arbitrary class files from the serialization function that is used by	by defining the following system properties: ply be bypassed by appending a '/' at the a3457f09ee76%40%3Cusers.tapestry.apache.-
	SM)					lows an attacker to gain remote code code via a crafted serialized Java classpath by providing a crafted asset Cisco Security Manager could allow	hazelcast.serialization.filter.enabled, end of the URL: 'http://localhost:8080/assets/ org%3E) and https://cve.mitre.org/cgi-
						execution via Java deserialization. object. file URL. An attacker is able to down-an unauthenticated, remote attacker	hazelcast.serialization.filter.black-something/services/AppModule.class/' (source: bin/cvename.cgi?name=CVE-2020-17531)
	Red Hat JBoss Gradle Enter-	CVE-2016-CVE-2020-	https://developers.redhat.com/ https://mvnrepository.com/	JBoss EAP 4 and 5 JMX servlet is ex-load the file AppModule.class by to execute arbitrary commands on an	list.classes, hazelcast.serialization.filter.black-Red Hat does not fix the issue because JBoss EAP X https://lists.apache.org/thread.html/r237ff-
	Enterprise prise Maven	7065 15777	products/eap/download artifact/com.gradle/gradle-	posed on port 8080/TCP with authen-requesting the URL 'http://localhost: affected device. These vulnerabilities	list.packages, hazelcast.serialization.filter.white-4 is out of maintenance support and JBoss EAP 7f286bda31682c254550c1ebf92b0ec61329b-
	Application Extension			enterprise-maven-extension	tication by default. The communica-8080/assets/something/services/ are due to insecure deserialization of	list.classes 5 is close to the end of its maintenance period and 32fbeb2d1c8751@%3Cusers.tapestry.apache.-
	Platform (Jboss-			tion employs serialized Java objects, AppModule.class' which contains a user-supplied content by the affected	hazelcast.serialization.filter.white-(see https://seclists.org/fulldisclosure/2016/Nov/ org%3E)
	EAP) 4 and			encapsulated in HTTP requests and re-HMAC secret key. software. An attacker could exploit	list.packages (see https://docs.hazelcast.org/ 143 and https://seclists.org/fulldisclosure/2016/
	5 Apache Tomcat CVE-2020-	https://github.com/apache/	sponses. The server deserializes these Deserialization flaw in session persis-these vulnerabilities by sending a ma-	docs/3.10.5/manual/html-single/ Nov/143) Update the class FileStore	with	X
				9484	tomcat	objects. This behavior can be exploited tence storage FileStore leading to re-licious serialized Java object to a spe-	index.html#untrusted-deserialization-some checks (patch in	https://
						to cause a denial of service and poten-mote code execution cific listener on an affected system. A	protection) github.com/apache/tomcat/commit/
	Apache	OF-	CVE-2016-	http://archive.apache.org/dist/	Remote attackers can execute arbitrary tially execute arbitrary code successful exploit could allow the at-	Update commons collections to 4.1 and bb33048e3f9b4f2b70e4da2e6c4e34ca89023b1b)	X
	Biz	12.04.x	2170	ofbiz/	commands via a crafted serialized Java tacker to execute arbitrary commands	Comment out RMI related code (see https://
	<	12.04.06			object, related to the Apache Com-on the device with the privileges of NT	issues.apache.org/jira/browse/OFBIZ-6942, https:
	and 13.07.x <			mons Collections library AUTHORITY\SYSTEM on the Win-	//markmail.org/message/nh6csf4fun5n6e23 and
	13.07.03				dows target host. Cisco has not re-	https://issues.apache.org/jira/browse/OFBIZ-
						leased software updates that address	6726)
						these vulnerabilities

Table 5 .

 5 [START_REF] Holzinger | An In-Depth Study of More Than Ten Years of Java Exploitation[END_REF] studied CVEs and applied patches. The first column designates the name of the studied vulnerable application; the column "CVE" mentions the CVE ID associated to the vulnerability; the third column "Code availability" indicates if the source code or the binary files are available: if yes, we give the URL for this code, otherwise we put "No"; the description of each vulnerability is presented in the fourth column; patching or workaround actions are described in the column "Applied patch"; the last three columns desingate the category of the vulnerability at hand: GA for GAdgets, DV for Deserialization Vulnerabilities and UC for Untrusted Code. The rows having UC as category are colored in gray because they are not in our scope of study in this article. Note that the complete table, with 104 CVEs, is available at https://github.com/software-engineering-and-security/java-deserialization-rce External patch (Update commons collections to 4.1 and Comment out RMI related code (see https://issues.apache.org/jira/ browse/OFBIZ-6942, https://markmail.org/ message/nh6csf4fun5n6e23 and https: //issues.apache.org/jira/browse/OFBIZ-Red Hat does not fix the issue because JBoss EAP 4 is out of maintenance support and JBoss EAP 5 is close to the end of its maintenance period (see https://seclists.org/ fulldisclosure/2016/Nov/143 and https:// seclists.org/fulldisclosure/2016/Nov/143)

	Add	an	allow-list	in	a	class	X
	ValidatingObjectInputStream (patch ob-
	tained by doing the diff between the vulnerable
	1.5.3 and the non-vulnerable 1.6 versions)

Table 8 .

 8 Analysis of the patches of 25 open source vulnerable applications. In this table, the fourth column "Internal/External patch?" describes if the patch concerns the code of the application itself (Internal

manager.paypal.com

https://www.equifax.com/

CVE refers to Commons Vulnerabilities Exposures. According to the Mitre terminology, a CVE is identified using an ID which is "a unique, alphanumeric identifier assigned by the CVE Program. Each identifier references a specific vulnerability. "[30, 31]

https://cve.mitre.org/

https://cve.mitre.org/find/search_tips.html

Imen Sayar, Alexandre Bartel, Eric Bodden, and Yves Le Traon

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-26857

information about a cyber attack in Solarwinds are available in https://www.secureworld.io/industry-news/solarwinds-cyber-attack-impact-update

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.

Appendix A Vulnerable applications and their patches

Create a whitelist of classes that are available to participate in the RichFaces resource deserialisation process https://www.bleathem.ca/blog/ richfaces-security-advisory-cve-2013-2165/ and https://codewhitesec.blogspot.com/2018/05/ poor-richfaces.html X Android < 5.0.0 CVE-2014-7911 https://android.googlesource.com/?format=HTML luni/src/main/java/java/io/-ObjectInputStream.java in the java.io.ObjectInputStream implementation does not verify that deserialization will result in an object that met the requirements for serialization, which allows attackers to execute arbitrary code via a crafted finalize method for a serialized object in an ArrayMap Parcel within an intent sent to system_service, as demonstrated by the finalize method of android.os.BinderProxy Add some checks that the class being deserialized matches the type information (enum, serializable, externalizable) held in the stream. Delayed static initialization of classes until the type of the class has been validated against the stream content in some cases. (see https://android.googlesource.com/platform/libcore/+/738c833d38d41f8f76eb7e77ab39a-dd82b1ae1e2%5E%21/#F0 and https://android.googlesource.com/platform/libcore/+/738c833d38d41f8f76eb7e77ab39a-dd82b1ae1e2) X Atlassian Bamboo before 5.9.9 and 5.10.x before 5.10.0 CVE-2014-9757 https://www.atlassian.com/ software/bamboo/downloadarchives

The Ignite Realtime Smack XMPP API, as used in Atlassian Bamboo before 5.9.9 and 5.10.x before 5.10.0, allows remote configured XMPP servers to execute arbitrary Java code via serialized data in an XMPP message The origin of the attack is the Smack library used in Bamboo. The patched version Bamboo 5.10.0 uses an updated version of the smack library in which a lot of modifications are brought: removing some classes (like Connection, Chat, ConnectionManager), modify the class XMPPConnection into an Interface , etc. (Patch obtained doing the diff between the version 5.9.7 and 5.10.0 of Bamboo, and more preciely the smack library). X Atlassian Bamboo 2.2 before 5.8.5 and 5.9.x before 5.9.7 CVE-2015-6576 https://www.atlassian.com/ software/bamboo/downloadarchives Bamboo 2.2 before 5.8.5 and 5.9.x before 5.9.7 allows remote attackers with access to the Bamboo web interface to execute arbitrary Java code via an unspecified resource.

Removes the deserializeObject method from the DeliverMessageServlet vulnerable class.

X

Atlassian Bamboo before 5.9.9 and 5.10.x before 5.10.0 CVE-2015-8360 https://www.atlassian.com/ software/bamboo/downloadarchives An unspecified resource in Atlassian Bamboo before 5.9.9 and 5.10.x before 5.10.0 allows remote attackers to execute arbitrary Java code via serialized data to the JMS port.

Use of black and white lists for serialization (patch obtained using the diff between the versions 5.10.0 and 5.9.7: there are two files serialization-blacklist.list and serialization-whitelist.list in the path "atlassian-bamboo-5.