Deserialization Is a Core Component of Web Applications
At the heart of the essentially limitless realm of information technology is data storage and transfer. Inextricably interlaced with this is a process of data formatting that must occur prior to deposition in a database, interaction with an application programming interface (API), or transmission over a network, since only formatted data can be stored and transferred. Complex data structures cannot be stored in databases and transferred across network nodes without a ubiquitous form of preprocessing to a byte stream known as serialization.
Accordingly, in the latter scenario of receiving data transferred across a network, what allows for a previous state of existence on one node for a data object to be identically reconstituted from a byte stream on another is a process known as deserialization. If data transfer can be viewed as the linchpin of modern web applications, then the reiterative cycle of serialization and deserialization is one of the core processes that makes data circulation, and by extension, web applications possible. Everyday functions of web applications are accomplished through serialization, including:
- Data transfers through remote and inter-process communications
- Caching and data persistence
- Storage to databases, servers, and file architectures
- Authentication keys for APIs and cookies for transfer protocols
Application Security Risks Presented by Insecure Deserialization
Although intrinsically innocuous, the deserialization process can represent a significant application vulnerability in a security framework. Insecure deserialization, the unpacking and reconstitution of user-supplied data, represents an application vulnerability in which all serialized data structures are treated the same—that is, by default, data received from an unvalidated source is treated the same as data received from a validated one. If exploited, data deserialized insecurely can serve as an embarkation point for a cascading series of cyberattacks, including denial of service (DoS), authentication bypass, remote code execution attacks, and SQL injection.
To illustrate, an application attack can assail a web application by loading malicious code into a serialized object and pass it to the application. If the web application deserializes user-controlled input in the absence of any validation check, the malicious code is enabled to access more surface area of the application. Subsequently, this sets the table for the initiation of secondary application attacks that could potentially lead to sensitive data exposure.
Insecure deserialization vulnerabilities are currently listed as 8th on the OWASP list of Top 10 Web Application Security Risks. Although the prevalence of insecure deserialization vulnerabilities is relatively low, this could be a direct result of a relative lack of efficient tools available to identify deserialization vulnerabilities. Furthermore, human intervention is often requisite to validate any vulnerabilities that have been identified. Nevertheless, as more efficient diagnostic tools emerge, the number of known deserialization vulnerabilities is only expected to grow.
Contrast Security’s “2020 Application Security Observability Report” quantifies the number of applications with serious insecure deserialization vulnerabilities at only 1%. Although this may seem a trivial number, it should be representative of a sizeable risk due to the fact that applications can experience as much as 13,000 attacks per month, and if exploited, the fallout can be severe.
Additionally, while serialization is a prevalent feature of essentially all web application programming languages, there are idiosyncrasies involved pertaining to how each of them serializes data. Thus, this also means that some languages are more susceptible to deserialization attacks than others, and these vulnerabilities have been identified in all prominent programming languages: Java, .NET, PHP, Ruby, Node.js, and Python. With respect to the topic of security vulnerabilities of deserialized data, Java security holds particular pertinence, as summarized in the “2020 Application Security Observability Report:”
“While not as common as it used to be, [insecure deserialization] can still be dangerous. Organizations should especially pay attention to Java applications, where many deserialization risks continue to persist.”
Identifying Deserialization Vulnerabilities During Application Development
In order to meet the aggressive time-to-market requirements demanded by digital transformation, many organizations are embracing Agile and DevOps approaches to application development. However, legacy application security approaches are point in time and are inaccurate—generating large volumes of false positives while missing true vulnerabilities (false negatives). As a result of the piles of false positives that accumulate, alert noise becomes a factor and security and development teams are simply unable to triage and diagnose all of the alerts; this is one of the causes of false positives.
Java applications tend to have the highest rate of deserialization vulnerabilities, and organizations need to pay the closest attention to them. Deserialization vulnerabilities also have the highest rate of prevalence in government and healthcare.
How to Protect Applications Against Insecure Deserialization
Unfortunately, a panacea for protecting web applications against all iterations of insecure deserialization attacks would be hard to come by. Further, the approach of completely exempting a web application from performing deserialization through its own logic does not entirely eradicate the threat either, since myriad other components of the application stack, most notably external libraries, do employ this process. A handful of web application security solutions are recommended to defend against insecure deserialization attacks including web application firewalls (WAFs), blacklisting, and whitelisting.
Of course, for every advantage that each of these security measures offers, there also exists an accompanying disadvantage. To illustrate, WAFs, perimeter network gatekeepers that are applied to restrict HTTP traffic entering and exiting applications, are effective and practical due to their customizability. However, the resources required to customize, and more importantly, maintain the WAF throughout the application life cycle can be significant and costly. Further, WAFs generate a huge number of false positives that can quickly consume significant time to triage and diagnose.
Alternatively, another approach to restricting network traffic is blacklisting. Blacklisting entails supplementing the application with the knowledge of which classes of data objects to reject due to security risks. Although blacklisting can be leveraged to protect an application, this strategy is also flawed in that the blacklist has to be maintained and also by the fact that only blacklist threats that you are already aware of can be blacklisted. The resulting false negatives can present a serious risk to organizations.
For this reason, an alternative approach to surmount the limitations of blacklisting is whitelisting. It involves enumerating a list of allowed classes of data objects to be used for the application. Even though it is considered a better approach than blacklisting, this strategy has its own disadvantages. Specifically, whitelisting not only requires maintenance of a relatively long list of allowed classes but also needs the generation of a new list for each release of the application. Thus, whitelisting can manifest as an arduous process that results in extended timelines for application development and deployment, and if whitelist updates are neglected, this can lead to false positives that are also undesirable.
Therefore, a drawback of all three of these aforementioned security strategies is requisite human intervention for proper implementation and administration, especially with respect to the pen testing required to identify vulnerabilities. One key measure that can be taken to reduce risk is to avoid the native deserialization formats employed by programming languages. By using XML or JSON, language-agnostic, data-only formats, the risk of exploiting deserialization logic as a mode of attack gets significantly reduced. Inconveniently, the only foolproof approach to thwart insecure deserialization attacks would be to disallow serialized objects from unvetted sources or only accept serialized objects exclusively derived from primitive data types. If this is not a practical strategy, other guidelines suggested by OWASP include:
- Since the application code often anticipates a defined set of classes, strong type constraints applied during the deserialization process, prior to object creation
- The isolation and execution of code that will deserialize in a low-privilege environment
- Logging exceptions and failures encountered during deserialization
- Deserialization vigilance and flagging of users that constantly deserialize
To this end, runtime application self-protection (RASP) has emerged as a preeminent component of the DevSecOps approach of the software development life cycle (SDLC). Embedding security within the software running in production, RASP detects attacks when they attempt to exploit a vulnerability—known and unknown—and blocks them before they can exercise the vulnerability. This includes insecure deserialization. Credited to being fixed in the application as a server-side process, it is able to identify, deter, and neutralize attacks contemporaneously because it can monitor application behavior and context—without the need for human intervention. This is a superior feature of RASP not found in more conventional security technologies.
Solving Insecure Deserialization Application Attacks
A hallmark of digital technology is its perpetual state of evolution. Application development is constantly changing at a breakneck pace and each web application is built by its own specific method to serve its own specific function. Consequently, every web application can be assailed in its own unique way, and web application vulnerabilities represent the most common initiator of data breaches. Due to the widespread adoption of Agile and DevOps to accelerate application development cycles, application vulnerabilities like insecure deserialization will continue to be a growing problem.
Having an application security platform approach using instrumentation, whereby security is embedded in the software and shifted left so that developers can detect and remediate vulnerabilities when they write code and extended to the right into production runtime, is crucial. Remediating insecure deserialization vulnerabilities early in development is significantly less costly and time-consuming than waiting until later in development. At the same time, vulnerabilities in production runtime will occur and RASP using security instrumentation is critical.