Insecure Deserialization, also known as Untrusted Deserialization, is a serious category of Application Security issues potentially affecting most modern systems. In fact, Insecure Deserialization is part of the OWASP Top 10 ranking of risks, as of the current edition (2017).
Some recent application security incidents involving Insecure Deserialization vulnerabilities are the following:
|CVE-2019-6503||Affects Chatopera, a Java app. Deserialization issue leads to remote code execution|
|CVE-2019-10068||Remote code execution in .NET app Kentico. One of the most recent vulnerabilities.|
|CVE-2018-7489||Remote code execution in systems that include Java Jackson XML functionality, similar to the example we provide below.|
|CVE-2018-6496, CVE-2018-6497||Unsafe deserialization leading to cross-site request forgery.|
|CVE-2018-19362||Can prevent normal operation of JBoss due to a XML Jackson vulnerability.|
|CVE-2018-1851||String formatting issues in Microsoft systems allows remote execution.|
|CVE-2017-9805||Related to Struts handling of XML deserialization, leads to remote execution. Very similar to the example described below.|
The complete list as tracked by the CVE is quite long. In fact, the media declared 2016 as the Java deserialization apocalypse year. All this justifies the OWASP decision to include this category in its Top 10 Ranking!
Understanding Insecure Deserialization
To understand this category of risks, let’s take one step back and start with serialization.
Complex modern systems are highly distributed. As the components communicate with each other and share information (such as moving data between services, storing information, etc), the native binary format is not ideal. In short, serialization is the process of turning this binary data into a string (ascii characters) so it can be moved using standard protocols.
Serialization operations are extremely common in architectures that include APIs, microservices, and client-side MVC. When the data being serialized and deserialized is trusted (under the control of the system), there are no risks.
However, when the input can be modified by the user, the result is an untrusted deserialization vulnerability. In this case, the conversion back from string to binary (deserialization) is a delicate operation prone to abuse. The typical course of action is to prepare a payload that includes remote code execution in the targeted machine. Often, the goal is to run system commands.
Any serialized data used by an application is at risk of manipulation, so ideally it should be accompanied by a cryptographic signature that enables integrity checks. This validation would prevent tampering of the serialized data. Another mitigation strategy includes not using binary formats, and choose alphanumeric standardized formats such as JSON and YAML.
Insecure Deserialization example
A well-known Insecure Deserialization example is the Struts 2 remote execution incident, which gained worldwide attention in 2017 for being the attack vector exploited in the Equifax hack.
Here is an example of remote execution related to that particular issue:
The Insecure Deserialization attack sequence that the video describes is:
1. To start configuring the malicious request, we set an HTTP header parameter to XML format.
2. We now build the XML payload. In our example, the payload is a static construction under the constant xmlPayload. This format is common, and it can be easily integrated in automated attack tools such as Metasploit.
3. The key element in the payload is a collection of classes that Struts will reassemble as part of the request preprocessing. Included in this collection, is the class type, along with the parameter that the class takes. Notably, if the class type is a ProcessBuilder, Struts will accept and execute this input. In sum, this is the core exploit:
<next class="java.lang.ProcessBuilder"> <command> %s </command> <redirectErrorStream>false</redirectErrorStream> </next>
4. Frequently, Insecure Deserialization involves remote execution. The command to be executed server-side is represented by the variable %s. In our video example, we chose to remotely start the Calculator app in the server running the vulnerable Struts system. The particular command we are launching is:
5. Simply by constructing the request as described above, and sending it to a vulnerable Struts server, we have managed to run remote code. A common step at this point would be to start a Meterpreter session back to the attacker’s machine and loot the system.
6. Next, in the video, we activate Hdiv RASP Protection, which prevents Insecure Deserialization natively, with no need to create a patch and/or rule for this particular exploit. The installation of Hdiv RASP is as easy as including the following parameter in your web application server launch command
7. As we see in the video, once Hdiv RASP is running, the Insecure Deserialization attack is blocked, and the Console shows the relevant information.
SAST, DAST, and WAF solutions are not enough
Untrusted deserialization attacks are closely related to the runtime process and the actions can be very dynamic. Let’s look at some general ideas concerning active mitigation of insecure deserialization:
1. Why traditional AST tools can’t solve Insecure Deserialization
Mainstream Application Security Testing (AST) tools such as SASTs struggle to help fixing insecure Deserialization issues. Even though SASTs can detect the source code “hot” calls that could indicate an Insecure Deserialization vulnerability, the operation is so common that the information that SASTs can provide is near useless.
On the other hand, AST tools that have a runtime visibility of the system (Dynamic AST) can only test known payloads. DASTs will not identify undocumented vulnerabilities that are particular to your application.
2. WAFs and ngWAFs don’t protect from all Insecure Deserialization issues
WAFs are a mature defense technology that work at the edge of the application by creating a perimeter. This means that WAFs don’t have visibility of the application internals, and no visibility of runtime execution.
Due to this external-only approach, the only solution is applying input validation. So even though WAFs can try to protect from exploits related to Untrusted Deserialization, the security will be very weak and limited to known exploits. In other words, based on blacklists.
Insecure Deserialization Prevention
As described above, to effectively block an Insecure Deserialization attack, the defenses must have excellent visibility of the underlying application architecture, and visibility of the data flow during runtime.
Hdiv RASP Protection, a technology based on instrumentation, covers these two requirements. As a result, Hdiv Protection does not need to build lists of patterns (blacklists) to match against the payloads, since they provide protection by design.
Most of Insecure Deserialization attacks try to execute commands using input data that has been provided by the request or the database. Thanks to the data flow control provided by Hdiv Protection (RASP), it is possible to understand how the data coming from the request or the database is used during the execution, thereby blocking any attempt to execute commands from such sources and totally avoiding this kind of issue.
Key take-aways to prevent Insecure Deserialization attacks:
These are our top recommendations to properly solve Insecure Deserialization vulnerabilities from an architectural point of view. From a practical point of view, RASP-style protection will cover Insecure Deserialization issues:
- Use language-agnostic formats: prefer standard formats such as JSON or YAML as opposed to native binary formats.
- Include integrity checks: when possible, include positive validation based on signatures for serialized data. Never trust data that has been provided by the user.
- Ensure that your protection tool has full visibility: avoid protection based on blacklisting or pattern matching (such as WAF and DAST) because it is not flexible enough to block unknown threats. RASPs on the other hand enjoy full visibility.
- Prevent remote execution: one of the most frequent and pernicious effects of Insecure Deserialization is execution of remote code. RASPs wrap your application to ensure that no remote execution occurs.
Thanks for reading! If you are curious about Hdiv RASP Protection, drop us a note (daniel at hdivsecurity dot com) and we will be happy to review in detail.