Welcome to Secumantra! In this post, we’re going to talk about the number eight vulnerability from OWASP Top Ten – Insecure Deserialization.
OWASP (Open Web Application Security Project) is a nonprofit foundation that works to improve the security of software. OWASP Foundation is globally recognized by developers as the first step towards more secure coding. It releases OWASP Top Ten list every 2-3 years sharing the most critical security risks to modern web applications.
Serialization vs Deserialization
Serialization is the process of turning some object (structured data) into a data format (stream of bytes – ascii characters) that can be easily shared, stored and restored later. People often serialize objects in order to save them to storage, or to send as part of communications between two services.
Deserialization is the reverse of that process, taking data structured from some format, and rebuilding it into an object. It is the process of recovering the data’s original structure from the stream of bytes. Today, the most popular data format for serializing data is JSON. Another popular data format was XML, which was used heavily few years back.
For example, it is possible to just JSON-encode all the data in the object and use it as it is. Developers generally know that user input is not to be trusted, serialized objects are seen as something different and forgotten to verify. In these scenarios, insecure deserialization is just another way of sending the payload which then affects an underlying vulnerability.
What is insecure deserialization?
Web applications make use of serialization and deserialization on a regular basis. Note that safe deserialization of objects is normal practice in software development. The trouble however, starts when deserializing untrusted user input.
Many programming languages offer a native capability for serializing objects. These native formats usually offer more features than JSON or XML, including customizability of the serialization process. Unfortunately, the features of these native deserialization mechanisms can be repurposed for malicious effect when operating on untrusted data.
This potentially enables an attacker to manipulate serialized objects in order to pass harmful data into the application code. Insecure deserialization is when an attacker inserts untrusted input into your web application to execute malicious code. The reason cyber criminals are able to do this is because the user input is not validated on the web application side.
Attacks against deserializers have been found to allow denial-of-service, access control, and remote code execution (RCE) attacks.
Impacts of insecure deserialization
As per OWASP, applications and APIs will be vulnerable if they deserialize hostile or tampered objects supplied by an attacker. This can result in two primary types of attacks:
- Object and data structure related attacks where the attacker modifies application logic or achieves arbitrary remote code execution if there are classes available to the application that can change behavior during or after deserialization.
- Typical data tampering attacks such as access-control-related attacks where existing data structures are used but the content is changed.
Serialization may be used in applications for:
- Remote and inter-process communication (RPC/IPC)
- Wire protocols, web services, message brokers
- Databases, cache servers, file systems
- HTTP cookies, HTML form parameters, API authentication tokens
Serialization and deserialization vary greatly depending on the programming language, serialization formats and software libraries used. Fortunately, there’s no ‘one-size-fits-all’ approach to attacking an insecure deserialization vulnerability. While this makes the vulnerability harder to find and exploit, it by no means makes it any less dangerous.
Examples – Attack Scenarios
- A React application calls a set of Spring Boot microservices. Being functional programmers, they tried to ensure that their code is immutable. The solution they came up with is serializing user state and passing it back and forth with each request. An attacker notices the “R00” Java object signature, and uses the Java Serial Killer tool to gain remote code execution on the application server.
- A PHP forum uses PHP object serialization to save a “super” cookie, containing the user’s user ID, role, password hash, and other state:
- An attacker changes the serialized object to give themselves admin privileges:
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. If that is not possible, OWASP recommends to consider one of more of the following:
- Implementing integrity checks such as digital signatures on any serialized objects to prevent hostile object creation or data tampering.
- Enforcing strict type constraints during deserialization before object creation as the code typically expects a definable set of classes. Bypasses to this technique have been demonstrated, so reliance solely on this is not advisable.
- Isolating and running code that deserializes in low privilege environments when possible.
- Log deserialization exceptions and failures, such as where the incoming type is not the expected type, or the deserialization throws exceptions.
- Restricting or monitoring incoming and outgoing network connectivity from containers or servers that deserialize.
- Monitoring deserialization, alerting if a user deserializes constantly.
- Using language-agnostic methods for deserialization such as JSON, XML or YAML might significantly reduce the risk of introducing insecure deserialization.
Insecure deserialization typically arises because there is a general lack of understanding of how dangerous deserializing user-controllable data can be. Ideally, user input should never be deserialized at all.
OWASP Risk Rating
Let us take a look at the OWASP overview and risk rating –
Exploiting insecure deserialization has a reputation for being difficult. However, it can sometimes be much simpler than you might think. Manual work is often needed to exploit this issue, which makes it less likely to be abused through automated attacks. However, if an exploit is once compiled towards one system, it can be automated towards all other systems running the same applications.
The impact depends on how the serialized object is used. Remote code execution or remote command execution, that would be considered the most critical, is absolutely a possibility given the circumstances.
An insecure deserialization happens for web applications which frequently serialize and deserialize data. Now deserialization data from untrusted sources may lead to remote code execution. Insecure deserialization flaws can enable an attacker to execute code in the application remotely, tamper or delete serialized (written to disk) objects, conduct injection attacks, and elevate privileges.
Generally speaking, deserialization of user input should be avoided unless absolutely necessary. The high severity of exploits that it potentially enables, and the difficulty in protecting against them, outweigh the benefits in many cases.
If you do need to deserialize data from untrusted sources, incorporate robust measures to make sure that the data has not been tampered with. For example, you could implement a digital signature to check the integrity of the data. However, remember that any checks must take place before beginning the deserialization process.
When securing your applications against any critical vulnerability (specially from OWASP Top Ten), it is always a good practice to follow defense in depth strategy.
Thank you for reading. Stay Safe, Stay Secure!