CA2301: Roep BinaryFormatter.Deserialize niet aan zonder eerst BinaryFormatter.Binder in te stellen
Eigenschappen | Weergegeven als |
---|---|
Regel-id | CA2301 |
Titel | Roep BinaryFormatter.Deserialize niet aan zonder eerst BinaryFormatter.Binder in te stellen |
Categorie | Beveiliging |
Oplossing is brekend of niet-brekend | Niet-brekend |
Standaard ingeschakeld in .NET 9 | Nee |
Oorzaak
Er System.Runtime.Serialization.Formatters.Binary.BinaryFormatter is een deserialisatiemethode aangeroepen of verwezen zonder de Binder eigenschappenset.
Deze regel analyseert standaard de hele codebasis, maar dit kan worden geconfigureerd.
Waarschuwing
Het beperken van typen met een SerializationBinder kan niet alle aanvallen voorkomen. Zie de beveiligingshandleiding binaryFormatter voor meer informatie.
Beschrijving van regel
Onveilige deserializers zijn kwetsbaar wanneer niet-vertrouwde gegevens worden gedeserialiseerd. Een aanvaller kan de geserialiseerde gegevens wijzigen zodat onverwachte typen worden opgenomen om objecten met schadelijke bijwerkingen te injecteren. Een aanval op een onveilig deserializer kan bijvoorbeeld opdrachten uitvoeren op het onderliggende besturingssysteem, communiceren via het netwerk of bestanden verwijderen.
Met deze regel worden aanroepen of verwijzingen van de deserialisatiemethode gevonden System.Runtime.Serialization.Formatters.Binary.BinaryFormatter wanneer BinaryFormatter deze niet is Binder ingesteld. Als u een deserialisatie niet wilt uitsluiten, BinaryFormatter ongeacht de Binder eigenschap, schakelt u deze regel en CA2302 uit en schakelt u de regel CA2300 in.
Schendingen oplossen
- Gebruik in plaats daarvan een beveiligde serialisatiefunctie en sta een aanvaller niet toe een willekeurig type op te geven dat moet worden gedeserialiseerd. Zie de voorkeursalternatieven voor meer informatie.
- Maak de geserialiseerde gegevens manipulatiebestendig. Na serialisatie tekent u de geserialiseerde gegevens cryptografisch. Voordat deserialisatie wordt gedeserialiseerd, valideert u de cryptografische handtekening. Beveilig de cryptografische sleutel tegen openbaarmaking en ontwerp voor sleutelrotaties.
- Deze optie maakt code kwetsbaar voor Denial of Service-aanvallen en mogelijke aanvallen voor het uitvoeren van externe code in de toekomst. Zie de beveiligingshandleiding binaryFormatter voor meer informatie. Beperk gedeserialiseerde typen. Implementeer een aangepaste System.Runtime.Serialization.SerializationBinder. Voordat u deserialiseren, stelt u de
Binder
eigenschap in op een exemplaar van uw aangepaste SerializationBinder in alle codepaden. Als het type onverwacht is, genereert u in de overschreven BindToType methode een uitzondering om deserialisatie te stoppen.
Wanneer waarschuwingen onderdrukken
BinaryFormatter
is onveilig en kan niet veilig worden gemaakt.
Code configureren om te analyseren
Gebruik de volgende opties om te configureren op welke onderdelen van uw codebase deze regel moet worden uitgevoerd.
U kunt deze opties configureren voor alleen deze regel, voor alle regels waarop deze van toepassing is, of voor alle regels in deze categorie (beveiliging) waarop deze van toepassing is. Zie de configuratieopties voor de codekwaliteitsregel voor meer informatie.
Specifieke symbolen uitsluiten
U kunt specifieke symbolen, zoals typen en methoden, uitsluiten van analyse. Als u bijvoorbeeld wilt opgeven dat de regel niet mag worden uitgevoerd op code binnen benoemde MyType
typen, voegt u het volgende sleutel-waardepaar toe aan een .editorconfig-bestand in uw project:
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType
Toegestane notaties voor symboolnamen in de optiewaarde (gescheiden door |
):
- Alleen symboolnaam (inclusief alle symbolen met de naam, ongeacht het type of de naamruimte).
- Volledig gekwalificeerde namen in de documentatie-id-indeling van het symbool. Voor elke symboolnaam is een voorvoegsel van het type symbool vereist, zoals
M:
voor methoden,T:
voor typen enN:
voor naamruimten. .ctor
voor constructors en.cctor
voor statische constructors.
Voorbeelden:
Optiewaarde | Samenvatting |
---|---|
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType |
Komt overeen met alle symbolen met de naam MyType . |
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 |
Komt overeen met alle symbolen met de naam of MyType1 MyType2 . |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) |
Komt overeen met een specifieke methode MyMethod met de opgegeven volledig gekwalificeerde handtekening. |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) |
Komt overeen met specifieke methoden MyMethod1 en MyMethod2 met de respectieve volledig gekwalificeerde handtekeningen. |
Specifieke typen en hun afgeleide typen uitsluiten
U kunt specifieke typen en hun afgeleide typen uitsluiten van analyse. Als u bijvoorbeeld wilt opgeven dat de regel niet mag worden uitgevoerd op methoden binnen benoemde MyType
typen en de afgeleide typen, voegt u het volgende sleutel-waardepaar toe aan een .editorconfig-bestand in uw project:
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType
Toegestane notaties voor symboolnamen in de optiewaarde (gescheiden door |
):
- Alleen de naam van het type (bevat alle typen met de naam, ongeacht het type of de naamruimte).
- Volledig gekwalificeerde namen in de documentatie-id-indeling van het symbool, met een optioneel
T:
voorvoegsel.
Voorbeelden:
Optiewaarde | Samenvatting |
---|---|
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType |
Komt overeen met alle typen met de naam MyType en alle afgeleide typen. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 |
Komt overeen met alle typen met de naam MyType1 of MyType2 en alle afgeleide typen. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType |
Komt overeen met een specifiek type MyType met een volledig gekwalificeerde naam en alle afgeleide typen. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 |
Komt overeen met specifieke typen MyType1 en MyType2 met de respectieve volledig gekwalificeerde namen en alle afgeleide typen. |
Voorbeelden van pseudocode
Schending
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class BookRecord
{
public string Title { get; set; }
public AisleLocation Location { get; set; }
}
[Serializable]
public class AisleLocation
{
public char Aisle { get; set; }
public byte Shelf { get; set; }
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(byte[] bytes)
{
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(bytes))
{
return (BookRecord) formatter.Deserialize(ms);
}
}
}
Imports System
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
<Serializable()>
Public Class BookRecord
Public Property Title As String
Public Property Location As AisleLocation
End Class
<Serializable()>
Public Class AisleLocation
Public Property Aisle As Char
Public Property Shelf As Byte
End Class
Public Class ExampleClass
Public Function DeserializeBookRecord(bytes As Byte()) As BookRecord
Dim formatter As BinaryFormatter = New BinaryFormatter()
Using ms As MemoryStream = New MemoryStream(bytes)
Return CType(formatter.Deserialize(ms), BookRecord)
End Using
End Function
End Class
Oplossing
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
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));
}
}
}
[Serializable]
public class BookRecord
{
public string Title { get; set; }
public AisleLocation Location { get; set; }
}
[Serializable]
public class AisleLocation
{
public char Aisle { get; set; }
public byte Shelf { get; set; }
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(byte[] bytes)
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Binder = new BookRecordSerializationBinder();
using (MemoryStream ms = new MemoryStream(bytes))
{
return (BookRecord) formatter.Deserialize(ms);
}
}
}
Imports System
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
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
<Serializable()>
Public Class BookRecord
Public Property Title As String
Public Property Location As AisleLocation
End Class
<Serializable()>
Public Class AisleLocation
Public Property Aisle As Char
Public Property Shelf As Byte
End Class
Public Class ExampleClass
Public Function DeserializeBookRecord(bytes As Byte()) As BookRecord
Dim formatter As BinaryFormatter = New BinaryFormatter()
formatter.Binder = New BookRecordSerializationBinder()
Using ms As MemoryStream = New MemoryStream(bytes)
Return CType(formatter.Deserialize(ms), BookRecord)
End Using
End Function
End Class