Deserialization is the process of converting serialized data (such as objects or data structures) back into their original form. Types allowed to be unserialized should be strictly controlled.

## Why is this an issue?

During the deserialization process, the state of an object will be reconstructed from the serialized data stream. By allowing unrestricted deserialization of types, the application makes it possible for attackers to use types with dangerous or otherwise sensitive behavior during the deserialization process.

### What is the potential impact?

When an application deserializes untrusted data without proper restrictions, an attacker can craft malicious serialized objects. Depending on the affected objects and properties, the consequences can vary.

### Remote Code Execution

If attackers can craft malicious serialized objects that contain executable code, this code will run within the application’s context, potentially gaining full control over the system. This can lead to unauthorized access, data breaches, or even complete system compromise.

For example, a well-known attack vector consists in serializing an object of type `TempFileCollection` with arbitrary files (defined by an attacker) which will be deleted on the application deserializing this object (when the finalize() method of the TempFileCollection object is called). These kinds of specially crafted serialized objects are called "gadgets".

### Privilege escalation

Unrestricted deserialization can also enable attackers to escalate their privileges within the application. By manipulating the serialized data, an attacker can modify object properties or bypass security checks, granting them elevated privileges that they should not have. This can result in unauthorized access to sensitive data, unauthorized actions, or even administrative control over the application.

### Denial of Service

In some cases, an attacker can abuse the deserialization process to cause a denial of service (DoS) condition. By providing specially crafted serialized data, the attacker can trigger excessive resource consumption, leading to system instability or unresponsiveness. This can disrupt the availability of the application, impacting its functionality and causing inconvenience to users.

## How to fix it

### Code examples

#### Noncompliant code example

With `BinaryFormatter`, `NetDataContractSerializer` or `SoapFormatter`:

    Dim myBinaryFormatter = New BinaryFormatter()
    myBinaryFormatter.Deserialize(stream) ' Noncompliant

With `JavaScriptSerializer`:

    Dim serializer1 As JavaScriptSerializer = New JavaScriptSerializer(New SimpleTypeResolver()) ' Noncompliant: SimpleTypeResolver is insecure (every type is resolved)
    serializer1.Deserialize(Of ExpectedType)(json)

#### Compliant solution

With `BinaryFormatter`, `NetDataContractSerializer` or `SoapFormatter`:

    NotInheritable Class CustomBinder
        Inherits SerializationBinder
        Public Overrides Function BindToType(assemblyName As String, typeName As String) As Type
            If Not (Equals(typeName, "type1") OrElse Equals(typeName, "type2") OrElse Equals(typeName, "type3")) Then
                Throw New SerializationException("Only type1, type2 and type3 are allowed")
            End If
            Return Assembly.Load(assemblyName).[GetType](typeName)
        End Function
    End Class

    Dim myBinaryFormatter = New BinaryFormatter()
    myBinaryFormatter.Binder = New CustomBinder()
    myBinaryFormatter.Deserialize(stream)

With `JavaScriptSerializer`:

    Public Class CustomSafeTypeResolver
        Inherits JavaScriptTypeResolver
        Public Overrides Function ResolveType(id As String) As Type
            If Not Equals(id, "ExpectedType") Then
                Throw New ArgumentNullException("Only ExpectedType is allowed during deserialization")
            End If
            Return Type.[GetType](id)
        End Function
    End Class

    Dim serializer As JavaScriptSerializer = New JavaScriptSerializer(New CustomSafeTypeResolver())
    serializer.Deserialize(Of ExpectedType)(json)

### Going the extra mile

Instead of using `BinaryFormatter` and similar serializers, it is recommended to use safer alternatives in most of the cases, such as `XmlSerializer` or `DataContractSerializer`.

If it’s not possible then try to mitigate the risk by restricting the types allowed to be deserialized:

- by implementing an "allow-list" of types, but keep in mind that novel dangerous types are regularly discovered and this protection could be insufficient over time.
- or/and implementing a tamper protection, such as message authentication codes (MAC). This way only objects serialized with the correct MAC hash will be deserialized.

## Resources

### Documentation

- Microsoft Learn - BinaryFormatter Class
- Microsoft Learn - NetDataContractSerializer Class
- Microsoft Learn - SoapFormatter Class
- Microsoft Learn - JavaScriptSerializer Class
- Microsoft Learn - XmlSerializer Class
- Microsoft Learn - DataContractSerializer Class

### Articles & blog posts

- Microsoft Learn - Deserialization risks in use of BinaryFormatter and related types
- OWASP - Deserialization Cheat Sheet
- Wikipedia - Message Authentication Codes (MAC)

### Standards

- OWASP - Top 10 2021 Category A8 - Software and Data Integrity Failures
- OWASP - Top 10 2017 Category A8 - Insecure Deserialization
- CWE - CWE-134 - Use of Externally-Controlled Format String
- CWE - CWE-502 - Deserialization of Untrusted Data