Why is this an issue?

During the deserialization process, the state of an object will be reconstructed from the serialized data stream which can contain dangerous operations.

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). This kind of types are called "gadgets".

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:

Noncompliant code example

For BinaryFormatter, NetDataContractSerializer, SoapFormatter serializers:

Dim myBinaryFormatter = New BinaryFormatter()
myBinaryFormatter.Deserialize(stream) ' Noncompliant: a binder is not used to limit types during deserialization

JavaScriptSerializer should not use SimpleTypeResolver or other weak resolvers:

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

LosFormatter should not be used without MAC verification:

Dim formatter As LosFormatter = New LosFormatter() ' Noncompliant
formatter.Deserialize(fs)

Compliant solution

BinaryFormatter, NetDataContractSerializer , SoapFormatter serializers should use a binder implementing a whitelist approach to limit types during deserialization (at least one exception should be thrown or a null value returned):

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") ' Compliant
        End If
        Return Assembly.Load(assemblyName).[GetType](typeName)
    End Function
End Class

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

JavaScriptSerializer should use a resolver implementing a whitelist to limit types during deserialization (at least one exception should be thrown or a null value returned):

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") ' Compliant
        End If
        Return Type.[GetType](id)
    End Function
End Class

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

LosFormatter serializer with MAC verification:

Dim formatter As LosFormatter = New LosFormatter(True, secret) ' Compliant
formatter.Deserialize(fs)

Resources