CA2311: Nicht deserialisieren, ohne zuerst NetDataContractSerializer.Binder festzulegen
Eigenschaft | Wert |
---|---|
Regel-ID | CA2311 |
Titel | Nicht deserialisieren, ohne zuerst NetDataContractSerializer.Binder festzulegen |
Kategorie | Security |
Fix führt oder führt nicht zur Unterbrechung | Nicht unterbrechend |
Standardmäßig in .NET 9 aktiviert | No |
Ursache
Es wurde eine Deserialisierungsmethode System.Runtime.Serialization.NetDataContractSerializer aufgerufen bzw. auf sie verwiesen, ohne dass Eigenschaft Binder eingestellt wurde.
Standardmäßig analysiert diese Regel die gesamte Codebasis, allerdings ist dies konfigurierbar.
Warnung
Durch das Einschränken von Typen mit einem SerializationBinder können nicht alle Angriffe verhindert werden. Weitere Informationen finden Sie im Sicherheitsleitfaden für BinaryFormatter.
Regelbeschreibung
Unsichere Deserialisierer sind beim Deserialisieren nicht vertrauenswürdiger Daten anfällig. Ein Angreifer könnte den serialisierten Daten unerwartete Datentypen hinzufügen, um Objekte mit schädlichen Auswirkungen einschleusen. Ein Angriff auf einen unsicheren Deserialisierer könnte z. B. Befehle auf dem dahinterliegenden Betriebssystem ausführen, über das Netzwerk kommunizieren oder Dateien löschen.
Diese Regel sucht System.Runtime.Serialization.NetDataContractSerializer-Deserialisierungsmethodenaufrufe oder -verweise auf diese, wenn für NetDataContractSerializer nicht dessen Binder eingestellt ist. Wenn Sie die Deserialisierung mit NetDataContractSerializer unabhängig von der Binder-Eigenschaft nicht zulassen möchten, deaktivieren Sie diese Regel und CA2312, und aktivieren Sie die Regel CA2310.
Behandeln von Verstößen
- Verwenden Sie stattdessen ein sicheres Serialisierungsmodul, und lassen Sie nicht zu, dass ein Angreifer einen beliebigen Typ zur Deserialisierung angibt. Weitere Informationen finden Sie in den bevorzugten Alternativen.
- Stellen Sie sicher, dass die serialisierten Daten nicht manipuliert werden können. Signieren Sie die serialisierten Daten nach der Serialisierung kryptografisch. Überprüfen Sie vor der Deserialisierung die kryptografische Signatur. Schützen Sie den Kryptografieschlüssel vor der Offenlegung, und richten Sie Schlüsselrotationen ein.
- Diese Option macht den Code anfällig für Denial-of-Service-Angriffe und mögliche Angriffe zur Remotecodeausführung in der Zukunft. Weitere Informationen finden Sie im Sicherheitsleitfaden für BinaryFormatter. Schränken Sie deserialisierte Typen ein. Implementieren Sie eine benutzerdefinierten System.Runtime.Serialization.SerializationBinder. Setzen Sie vor der Deserialisierung die
Binder
-Eigenschaft in allen Codepfaden auf eine Instanz Ihrer benutzerdefinierten SerializationBinder. Lösen Sie in der überschriebenen BindToType-Methode bei einem unerwarteten Typ eine Ausnahme aus, um die Deserialisierung zu stoppen.
Wann sollten Warnungen unterdrückt werden?
NetDataContractSerializer
ist unsicher und kann nicht sicher gemacht werden.
Konfigurieren des zu analysierenden Codes
Mithilfe der folgenden Optionen können Sie konfigurieren, für welche Teile Ihrer Codebasis diese Regel ausgeführt werden soll.
Sie können diese Optionen nur für diese Regel, für alle zutreffenden Regeln oder für alle zutreffenden Regeln in dieser Kategorie (Sicherheit) konfigurieren. Weitere Informationen finden Sie unter Konfigurationsoptionen für die Codequalitätsregel.
Ausschließen bestimmter Symbole
Sie können bestimmte Symbole, z. B. Typen und Methoden, von der Analyse ausschließen. Sie können beispielsweise festlegen, dass die Regel nicht für Code innerhalb von Typen namens MyType
ausgeführt werden soll, indem Sie einer EDITORCONFIG-Datei in Ihrem Projekt das folgende Schlüssel-Wert-Paar hinzufügen:
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType
Zulässige Formate für Symbolnamen im Optionswert (durch |
getrennt):
- Nur Symbolname (schließt alle Symbole mit dem Namen ein, unabhängig vom enthaltenden Typ oder Namespace)
- Vollqualifizierte Namen im Format der Dokumentations-ID des Symbols Jeder Symbolname erfordert ein Symbolartpräfix, z. B.
M:
für Methoden,T:
für Typen undN:
für Namespaces. .ctor
für Konstruktoren und.cctor
für statische Konstruktoren
Beispiele:
Optionswert | Zusammenfassung |
---|---|
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType |
Trifft auf alle Symbole namens MyType zu |
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 |
Trifft auf alle Symbole namens MyType1 oder MyType2 zu |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) |
Trifft speziell auf die Methode MyMethod mit der angegebenen vollqualifizierten Signatur zu |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) |
Trifft speziell auf die Methoden MyMethod1 und MyMethod2 mit den jeweiligen vollqualifizierten Signaturen zu |
Ausschließen bestimmter Typen und von diesen abgeleiteten Typen
Sie können bestimmte Typen und von diesen abgeleitete Typen aus der Analyse ausschließen. Wenn Sie z. B. festlegen möchten, dass die Regel nicht für Methoden innerhalb von MyType
-Typen und von diesen abgeleiteten Typen ausgeführt werden soll, fügen Sie einer EDITORCONFIG-Datei in Ihrem Projekt das folgende Schlüssel-Wert-Paar hinzu:
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType
Zulässige Formate für Symbolnamen im Optionswert (durch |
getrennt):
- Nur Typname (schließt alle Typen mit dem Namen ein, unabhängig vom enthaltenden Typ oder Namespace)
- Vollqualifizierte Namen im Dokumentations-ID-Format des Symbols mit einem optionalen Präfix
T:
Beispiele:
Optionswert | Zusammenfassung |
---|---|
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType |
Stimmt mit allen MyType -Typen und allen von diesen abgeleiteten Typen überein. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 |
Stimmt mit allen MyType1 - oder MyType2 -Typen und allen von diesen abgeleiteten Typen überein. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType |
Stimmt mit einem bestimmten MyType -Typ mit einem angegebenen vollqualifizierten Namen und allen von diesem abgeleiteten Typen überein. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 |
Stimmt mit bestimmten MyType1 - und MyType2 -Typen mit den entsprechenden vollqualifizierten Namen und allen von diesen abgeleiteten Typen überein. |
Pseudocodebeispiele
Verletzung
using System;
using System.IO;
using System.Runtime.Serialization;
[DataContract]
public class BookRecord
{
[DataMember]
public string Title { get; set; }
[DataMember]
public AisleLocation Location { get; set; }
}
[DataContract]
public class AisleLocation
{
[DataMember]
public char Aisle { get; set; }
[DataMember]
public byte Shelf { get; set; }
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(byte[] bytes)
{
NetDataContractSerializer serializer = new NetDataContractSerializer();
using (MemoryStream ms = new MemoryStream(bytes))
{
return (BookRecord) serializer.Deserialize(ms); // CA2311 violation
}
}
}
Imports System
Imports System.IO
Imports System.Runtime.Serialization
<DataContract()>
Public Class BookRecord
<DataMember()>
Public Property Title As String
<DataMember()>
Public Property Location As AisleLocation
End Class
<DataContract()>
Public Class AisleLocation
<DataMember()>
Public Property Aisle As Char
<DataMember()>
Public Property Shelf As Byte
End Class
Public Class ExampleClass
Public Function DeserializeBookRecord(bytes As Byte()) As BookRecord
Dim serializer As NetDataContractSerializer = New NetDataContractSerializer()
Using ms As MemoryStream = New MemoryStream(bytes)
Return CType(serializer.Deserialize(ms), BookRecord) ' CA2311 violation
End Using
End Function
End Class
Lösung
using System;
using System.IO;
using System.Runtime.Serialization;
public class BookRecordSerializationBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
// One way to discover expected types is through testing deserialization
// of **valid** data and logging the types used.
////Console.WriteLine($"BindToType('{assemblyName}', '{typeName}')");
if (typeName == "BookRecord")
{
return typeof(BookRecord);
}
else if (typeName == "AisleLocation")
{
return typeof(AisleLocation);
}
else
{
throw new ArgumentException("Unexpected type", nameof(typeName));
}
}
}
[DataContract]
public class BookRecord
{
[DataMember]
public string Title { get; set; }
[DataMember]
public AisleLocation Location { get; set; }
}
[DataContract]
public class AisleLocation
{
[DataMember]
public char Aisle { get; set; }
[DataMember]
public byte Shelf { get; set; }
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(byte[] bytes)
{
NetDataContractSerializer serializer = new NetDataContractSerializer();
serializer.Binder = new BookRecordSerializationBinder();
using (MemoryStream ms = new MemoryStream(bytes))
{
return (BookRecord) serializer.Deserialize(ms);
}
}
}
Imports System
Imports System.IO
Imports System.Runtime.Serialization
Public Class BookRecordSerializationBinder
Inherits SerializationBinder
Public Overrides Function BindToType(assemblyName As String, typeName As String) As Type
' One way to discover expected types is through testing deserialization
' of **valid** data and logging the types used.
'Console.WriteLine($"BindToType('{assemblyName}', '{typeName}')")
If typeName = "BinaryFormatterVB.BookRecord" Then
Return GetType(BookRecord)
Else If typeName = "BinaryFormatterVB.AisleLocation" Then
Return GetType(AisleLocation)
Else
Throw New ArgumentException("Unexpected type", NameOf(typeName))
End If
End Function
End Class
<DataContract()>
Public Class BookRecord
<DataMember()>
Public Property Title As String
<DataMember()>
Public Property Location As AisleLocation
End Class
<DataContract()>
Public Class AisleLocation
<DataMember()>
Public Property Aisle As Char
<DataMember()>
Public Property Shelf As Byte
End Class
Public Class ExampleClass
Public Function DeserializeBookRecord(bytes As Byte()) As BookRecord
Dim serializer As NetDataContractSerializer = New NetDataContractSerializer()
serializer.Binder = New BookRecordSerializationBinder()
Using ms As MemoryStream = New MemoryStream(bytes)
Return CType(serializer.Deserialize(ms), BookRecord)
End Using
End Function
End Class
Ähnliche Regeln
CA2310: Unsicheren Deserialisierer nicht verwenden: NetDataContractSerializer
CA2312: Vor dem Deserialisieren sicherstellen, dass NetDataContractSerializer.Binder festgelegt ist