OWASP Top10

Insecure Deserialization – How it works ? Impact, Prevention & Vulnerable Code Examples

This section will provide an overview of insecure deserialization, including its potential to expose websites to high-severity attacks. We will examine typical scenarios and demonstrate applicable techniques using concrete examples of deserialization in PHP, Ruby, and Java. Additionally, we will explore preventive measures to help you avoid insecure deserialization vulnerabilities in your own websites.

What is Serialization ?

Serialization is the process of converting an object’s state into a format that can be stored or transmitted over a network. In other words, it’s a way of turning a complex data structure or object into a sequence of bytes or text that can be easily transmitted or stored. 

What is Deserialization ?

The opposite of serialization is deserialization, which is the process of reconstructing the original object from its serialized form. Where as Serialization is commonly used in programming to save data, transfer objects between applications or systems, and enable remote procedure calls.

Serialization vs Deserialization

Serialization and deserialization are two closely related concepts in computer programming. Here are some key points to distinguish between the two:

Serialization:

  1. Serialization is the process of converting an object into a stream of bytes that can be stored in a file or transmitted over a network.
  2. Serialization is used to transfer objects between different systems, platforms, or programming languages.
  3. Serialized data is platform and language-independent, meaning that it can be deserialized on any system or platform that supports the serialization format.
  4. Serialization is often used for caching or persisting objects, as well as for communication between different components of a distributed system.
  5. Serialization can be done in different formats, such as JSON, XML, or binary.

Deserialization:

  1. Deserialization is the process of converting a stream of bytes back into an object.
  2. Deserialization is the opposite of serialization, and is used to reconstruct objects that were previously serialized.
  3. Deserialization requires the same serialization format as the one used for serialization, otherwise the process will fail.
  4. Deserialization can be vulnerable to attacks when untrusted data is passed to the deserialization process, allowing attackers to execute arbitrary code on the target system.
  5. Deserialization is an important part of many programming tasks, such as reading and writing data from files, and exchanging data over networks.

In summary, serialization is the process of converting objects into a format that can be stored or transmitted, while deserialization is the process of converting that format back into objects. Both are important for many programming tasks, but deserialization can be vulnerable to security attacks if not handled properly.

What is Insecure Deserialization ?

insecure deserialization

Insecure deserialization is a vulnerability that occurs when untrusted data is deserialized without proper validation or sanitization. This can allow an attacker to execute arbitrary code or perform other malicious actions by crafting a specially-crafted serialized object.

How Insecure Deserialization Vulnerability Arises:

Insecure deserialization vulnerabilities can arise due to a variety of reasons. Here are some of the common causes:

1. Lack of Input Validation:

One of the most common causes of insecure deserialization vulnerabilities is the lack of input validation. If an application deserializes data from an untrusted source without validating it properly, it can lead to the execution of malicious code.

2. Trusting Serialized Data:

Another common cause is blindly trusting serialized data without verifying that it matches a known and expected format. This can allow attackers to send malformed payloads that can cause the application to crash or execute arbitrary code.

3. Serialization Libraries:

In some cases, insecure deserialization vulnerabilities can arise due to flaws in the serialization libraries used by the application.

4. Serialization Format:

The serialization format used by the application can also play a role in the vulnerability. Some serialization formats, such as Java Serialization, have inherent vulnerabilities that can be exploited by attackers.

Here’s an example of insecure deserialization in Java:

import java.io.*;

public class User implements Serializable {

    private String name;

    private int age;

    // other fields and methods

    public static void main(String[] args) throws Exception {

        String serializedObject = args[0];

        ByteArrayInputStream bis = new ByteArrayInputStream(Base64.getDecoder().decode(serializedObject));

        ObjectInputStream ois = new ObjectInputStream(bis);

        User user = (User) ois.readObject();

        System.out.println("Deserialized user: " + user.getName() + ", " + user.getAge());

    }

}

In this example, we have a class called User that implements the Serializable interface, which means it can be serialized and deserialized. The main() method of the class demonstrates how a serialized User object can be deserialized from a Base64-encoded string.

Now, let’s say an attacker sends a specially-crafted serialized object that contains malicious code, like this:

rO0ABXNyACFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAABAAAAA/QAAAABAAAAAw==

When the main() method deserializes this object, it executes the following code:

new java.lang.ProcessBuilder("/bin/bash", "-c", "echo 'Code executed'").start()

This code launches a new process that echoes the message “Code executed”. An attacker could use this vulnerability to execute any arbitrary code they want, potentially leading to a complete compromise of the system.

This is just one example of how insecure deserialization can be exploited. The key takeaway is that deserializing untrusted data without proper validation can lead to serious security vulnerabilities. It’s important to ensure that deserialization is done safely and securely in all cases.

Impact of Insecure Deserialization:

Insecure deserialization can have severe consequences on the security and integrity of web applications. Attackers can exploit this vulnerability to execute arbitrary code, gain unauthorized access, or cause denial-of-service attacks. Here are some of the potential impacts of insecure deserialization:

1. Remote Code Execution (RCE):

Attackers can craft malicious payloads that can be deserialized by the application and execute arbitrary code, allowing them to take full control of the application and the underlying system.

2. Authentication Bypass:

Insecure deserialization can allow attackers to bypass authentication mechanisms and gain unauthorized access to sensitive resources or functionality.

3. Denial of Service (DoS):

Attackers can send malformed or large payloads that can cause the application to crash, potentially leading to a DoS attack.

4. Information Disclosure:

Insecure deserialization can also result in the disclosure of sensitive information, such as credentials, session tokens, or other sensitive data.

Popular Vulnerable Serialization Libraries

There have been several well-known vulnerabilities in serialization libraries that have allowed attackers to exploit insecure deserialization. Here are few examples:

1. Apache Struts:

Apache Struts is a widely-used web application development framework that includes a built-in serialization mechanism. In 2017, a critical vulnerability was discovered in the framework’s deserialization functionality, allowing attackers to execute arbitrary code on servers running Struts applications. This vulnerability was exploited in the Equifax data breach, among others.

2. Java’s native serialization:

Java includes a built-in serialization mechanism that can be used to serialize and deserialize objects. However, this mechanism has been found to be vulnerable to deserialization attacks. Because it’s included in the standard library and widely used, this vulnerability affects a large number of Java applications.

3. Jackson:

Jackson is a popular JSON parsing library for Java. In 2017, a vulnerability was discovered in the library’s deserialization functionality that allowed attackers to execute arbitrary code by crafting a malicious JSON object.

4. XStream:

XStream is a popular serialization library for Java that allows objects to be serialized to XML. In 2013, a critical vulnerability was discovered in XStream’s deserialization functionality that allowed attackers to execute arbitrary code.

5. .NET BinaryFormatter:

The .NET framework includes a BinaryFormatter class that can be used for serialization and deserialization. However, this class has been found to be vulnerable to deserialization attacks. In 2019, a critical vulnerability was discovered in the library’s deserialization functionality that allowed attackers to execute arbitrary code.

6. PHP’s unserialize function:

PHP includes a built-in unserialize function that can be used to deserialize data. However, this function is vulnerable to deserialization attacks when untrusted data is passed to it. In 2015, a vulnerability was discovered in the function that allowed attackers to execute arbitrary code on servers running PHP applications.

7. Ruby’s YAML module:

Ruby includes a YAML module that can be used for serialization and deserialization. In 2013, a critical vulnerability was discovered in the module’s deserialization functionality that allowed attackers to execute arbitrary code.

These are just a few examples of serialization libraries that have been found to be vulnerable to insecure deserialization attacks. It’s important to keep these vulnerabilities in mind when choosing serialization libraries for your applications and to ensure that you use them safely and securely.

Vulnerable Code Examples of Insecure Deseralization of Different Programming Languages

Here are some examples of insecure deserialization vulnerable code in different programming languages:

  1. Java:
public Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {

    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);

    ObjectInput in = new ObjectInputStream(bis);

    Object obj = in.readObject();

    in.close();

    return obj;

}

In this Java code, the deserialize() function deserializes a byte array into an Object without any input validation. An attacker could exploit this vulnerability by sending a maliciously crafted serialized object that could lead to remote code execution.

  1. Python:
import pickle

def unserialize(data):

    return pickle.loads(data)

In this Python code, the unserialize() function deserializes data using the pickle.loads() function without any input validation. An attacker could exploit this vulnerability by sending a maliciously crafted pickled object that could lead to remote code execution.

  1. PHP:
$data = unserialize($_COOKIE['session_data']);

In this PHP code, the unserialize() function is used to deserialize data from a user-supplied cookie without any input validation. An attacker could exploit this vulnerability by sending a maliciously crafted serialized object in the cookie that could lead to remote code execution.

  1. Ruby:
require 'yaml'

def unserialize(data)

  YAML.load(data)

end

In this Ruby code, the unserialize() function deserializes data using the YAML.load() function without any input validation. An attacker could exploit this vulnerability by sending a maliciously crafted YAML object that could lead to remote code execution.

These examples demonstrate how insecure deserialization vulnerabilities can occur in different programming languages when input is not properly validated. To prevent these types of vulnerabilities, it’s important to always validate input when deserializing data.

Detecting Insecure Deserialization Vulnerabilities –

There are several ways to determine whether your application is vulnerable to insecure deserialization:

1. Check the use of serialization libraries:

If your application uses a serialization library, it’s important to check whether the library has any known vulnerabilities. Some serialization libraries are more susceptible to deserialization attacks than others, so it’s important to choose a library that is secure and well-maintained.

2. Analyze code for deserialization vulnerabilities:

It’s important to analyze your application’s code for any instances where deserialization is used, and to check whether the deserialization process can be exploited by attackers. This can be done using static code analysis tools or by manually reviewing the code.

3. Use a vulnerability scanner:

Vulnerability scanners can be used to detect known vulnerabilities in your application, including vulnerabilities related to insecure deserialization. Many commercial and open-source scanners are available that can help identify potential security weaknesses in your application.

4. Conduct penetration testing:

Penetration testing can be used to simulate real-world attacks against your application, including attacks that exploit insecure deserialization. Penetration testing can help identify vulnerabilities that may not be detected by other testing methods.

5. Monitor for suspicious activity:

It’s important to monitor your application for any suspicious activity, such as unexpected network traffic or unusual system behavior, which may indicate that an attacker is attempting to exploit a deserialization vulnerability.

By taking these steps, you can identify potential vulnerabilities in your application related to insecure deserialization and take steps to remediate them before they can be exploited by attackers.

Preventing Insecure Deseralization:

Preventing insecure deserialization vulnerabilities requires a combination of secure coding practices, strong access controls, and monitoring. For example, let’s say you are developing a Java application that uses serialization and deserialization to store and retrieve user data. To prevent insecure deserialization, you can implement the following best practices:

Input Validation:

Always validate any input received from untrusted sources, including serialized data. This can include checking for data types, lengths, and format.

Secure Serialization Format:

Use a secure and widely adopted serialization format such as JSON or Protocol Buffers, which have built-in protections against certain types of attacks.

Access Controls:

Implement strict access controls and authentication mechanisms to prevent unauthorized access to deserialized objects.

Monitoring:

Monitor for unusual or unexpected activity related to deserialization, such as unusual traffic patterns or unusual objects being deserialized.

Limit Payload Sizes:

Limit the size of the payload that can be deserialized to prevent DoS attacks.

Use Trusted Serialization Libraries:

Use trusted and secure serialization libraries that are regularly updated and patched.

Use Security Tools:

Use security tools such as static and dynamic code analysis tools to detect and prevent insecure deserialization vulnerabilities.

Here is an example Java code snippet that demonstrates how to prevent insecure deserialization using the above best practices:

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.Serializable;

public class MyClass implements Serializable {

    private static final long serialVersionUID = 1L;

    private int myInt;

    private String myString;

    public MyClass(int myInt, String myString) {

        this.myInt = myInt;

        this.myString = myString;

    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {

        // Use a whitelist approach to check that the serialized object is of the expected class.

        if (!in.readUTF().equals("MyClass")) {

            throw new IOException("Invalid serialized object");

        }

        // Deserialize the object as expected.

        this.myInt = in.readInt();

        this.myString = in.readUTF();

    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        // Deserialize the object.

        byte[] serializedObject = {0x73, 0x72, 0x00, 0x10, 0x4d, 0x79, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x77, 0x00, 0x00, 0x00, 0x00,

                                   0x00, 0x00, 0x00, 0x02, 0x49, 0x00, 0x07, 0x6d, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};

        ByteArrayInputStream bis = new ByteArrayInputStream(serializedObject);

        ObjectInputStream in = new ObjectInputStream(bis);

        MyClass obj = (MyClass) in.readObject();

        System.out.println(obj.myString);

    }

}

In this example, we have defined a MyClass class that is serializable. We have also implemented the readObject method to perform additional validation during deserialization. In the readObject method, we check that the serialized object is of the expected class, using a whitelist approach. If the object is not of the expected class, we throw an exception.

In the main method, we deserialize a serialized MyClass object. We first create a ByteArrayInputStream from the serialized object, and then create an ObjectInputStream from the ByteArrayInputStream. We then read the MyClass object from the ObjectInputStream.

By following the above best practices and implementing additional validation during deserialization, we can prevent insecure deserialization vulnerabilities.

Popular Tools Used for Finding Insecure Deserialization Vulnerability

There are several tools available for detecting insecure deserialization vulnerabilities in web applications. Here are some popular ones:

Burp Suite: Burp Suite is a web application security testing tool that includes several extensions for detecting insecure deserialization vulnerabilities, such as JavaDS, YSoSerial.net, and Java-Deserialization-Scanner.

Java DS Burp Extension

JavaDS is a Burp Suite extension that can be used to detect and exploit Java deserialization vulnerabilities in web applications. Here are the steps to use JavaDS:

  • Install the JavaDS extension: Open Burp Suite and navigate to the “Extender” tab. Click on the “Extender” tab and then goto “BAppStore”. Browse to the JavaDS extension file and click on “Install” to install the extension.
  • Configure JavaDS: Once the JavaDS extension is installed, navigate to the “JavaDS” tab in the “Extender” tab. Here, you can configure the JavaDS extension settings, such as the payload and exploit method.
  • Scan for Java deserialization vulnerabilities: Use Burp Suite’s scanning feature to scan your web application for Java deserialization vulnerabilities. JavaDS should automatically detect any Java deserialization vulnerabilities found by Burp Suite.
  • Exploit Java deserialization vulnerabilities: Once you have identified a Java deserialization vulnerability in your web application, you can use JavaDS to exploit the vulnerability. Navigate to the “JavaDS” tab in the “Extender” tab and click on the “Exploit” button. JavaDS will send a payload to the vulnerable application and attempt to execute arbitrary code on the server.

Insecure Deserialization Practice Labs

Here are some online insecure deserialization vulnerability practice labs:

  • PortSwigger Web Security Academy: The PortSwigger Web Security Academy offers a free insecure deserialization lab that walks you through identifying and exploiting a Java deserialization vulnerability in a web application.
  • OWASP Vulnerable Web Applications Directory: The OWASP Vulnerable Web Applications Directory lists several vulnerable web applications that can be used for practice, including applications vulnerable to insecure deserialization.
  • Damn Vulnerable Web Application (DVWA): DVWA is a vulnerable web application that includes several security vulnerabilities, including an insecure deserialization vulnerability that can be used for practice.

Akshay Sharma

Inner Cosmos

Leave a Reply