Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
| Tulajdonság | Érték |
|---|---|
| Szabályazonosító | CA2302 |
| Cím | Győződjön meg arról, hogy a BinaryFormatter.Binder be van állítva a BinaryFormatter.Deserialize hívása előtt |
| Kategória | Biztonság |
| A javítás romboló vagy nem romboló | Nem törhető |
| Alapértelmezés szerint engedélyezve a .NET 10-ben | Nem |
| Alkalmazandó nyelvek | C# és Visual Basic |
Ok
A System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deszerializálási metódust hívtak meg, vagy hivatkoztak rá, és a Binder tulajdonság null értékű lehet.
Ez a szabály hasonló a CA2301-hez, de az elemzés nem tudja megállapítani, hogy a Binder szabály egyértelműen null értékű-e.
Ez a szabály alapértelmezés szerint a teljes kódbázist elemzi, de ez konfigurálható.
Figyelmeztetés
A szerializációbinderrel rendelkező típusok korlátozása nem tudja megakadályozni az összes támadást. További információt a BinaryFormatter biztonsági útmutatójában talál.
Szabály leírása
A nem biztonságos deszerializálók sebezhetők a nem megbízható adatok deszerializálásakor. A támadó úgy módosíthatja a szerializált adatokat, hogy váratlan típusokat is tartalmazzon, hogy kártékony mellékhatásokkal rendelkező objektumokat injektáljon. A nem biztonságos deszerializáló elleni támadás például parancsokat hajthat végre az alapul szolgáló operációs rendszeren, kommunikálhat a hálózaton keresztül, vagy fájlokat törölhet.
Ez a szabály megkeresi a System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deszerializálási metódus hívásait vagy hivatkozásait, amikor a Binder null értékű lehet. Ha a tulajdonságtól függetlenül szeretné letiltani a deszerializálástBinaryFormatter, tiltsa le ezt a Binder szabályt és a CA2301-et, és engedélyezze a CA2300 szabályt.
Szabálysértések kijavítása
- Ehelyett használjon biztonságos szerializálót, és ne engedélyezze a támadónak, hogy tetszőleges típust adjon meg a deszerializáláshoz. További információkért lásd az előnyben részesített alternatívákat.
- Tegye a szerializált adatokat manipulációbiztossá. A szerializálás után kriptográfiailag írja alá a szerializált adatokat. A deszerializálás előtt ellenőrizze a titkosítási aláírást. Védje meg a titkosítási kulcsot a nyilvánosságra hozataltól, és tervezzen kulcsforgatást.
- Ez a beállítás sebezhetővé teszi a kódot a szolgáltatásmegtagadási támadásokkal és az esetleges távoli kódvégrehajtási támadásokkal szemben a jövőben. További információt a BinaryFormatter biztonsági útmutatójában talál. Deszerializált típusok korlátozása. Egyéni System.Runtime.Serialization.SerializationBinder implementálás. A deszerializálás előtt minden kódútvonalon állítsa be a
Bindertulajdonságot az Ön egyéni SerializationBinder példányára. Ha a típus váratlan, a felülírt BindToType metódusban kivételt kell tenni a deszerializálás leállításához.
Mikor kell letiltani a figyelmeztetéseket?
BinaryFormatter nem biztonságos, és nem lehet biztonságossá tenni.
Kód konfigurálása elemzéshez
A következő beállítások segítségével konfigurálhatja, hogy a kódbázis mely részein futtassa ezt a szabályt.
Ezeket a beállításokat konfigurálhatja csak erre a szabályra, az összes szabályra, vagy az ebben a kategóriában szereplő összes szabályra (Biztonsági), amelyekre vonatkoznak. További információ: Kódminőségi szabály konfigurációs beállításai.
Adott szimbólumok kizárása
A excluded_symbol_names beállítással kizárhat bizonyos szimbólumokat, például típusokat és metódusokat az elemzésből. Ha például meg szeretné adni, hogy a szabály ne fusson a nevesített MyTypetípusok egyikén sem, adja hozzá a következő kulcs-érték párot a projekt egyik .editorconfig fájljához:
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType
Jegyzet
Cserélje le a XXXXCAXXXX részét a vonatkozó szabály azonosítójára.
Engedélyezett szimbólumnévformátumok a beállításértékben (a következővel |elválasztva):
- Csak szimbólumnév (a névvel ellátott összes szimbólumot tartalmazza, függetlenül attól, hogy milyen típusú vagy névtérrel rendelkezik).
- A szimbólum "dokumentációazonosító formátumában" szereplő teljes nevek. Minden szimbólumnévhez szimbólum típusú előtag szükséges, például
M:metódusokhoz,T:típusokhoz ésN:névterekhez. -
.ctorkonstruktorok és.cctorstatikus konstruktorok számára.
Példák:
| Beállítás értéke | Összegzés |
|---|---|
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType |
Megegyezik az összes elnevezett MyTypeszimbólummal. |
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 |
Az összes MyType1 vagy MyType2 nevű szimbólummal megegyezik. |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) |
Megfelel a megadott metódusnak MyMethod a megadott teljes jogosultsággal rendelkező aláírással. |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) |
Összepárosítja az adott metódusokat MyMethod1 és MyMethod2 a megfelelő teljesen minősített aláírásokkal. |
Adott típusok és származtatott típusok kizárása
A excluded_type_names_with_derived_types beállítás beállításával kizárhat bizonyos típusokat és azok származtatott típusait az elemzésből. Ha például meg szeretné adni, hogy a szabály ne fusson a nevesített MyType és származtatott típusok egyik metódusán sem, adja hozzá a következő kulcs-érték párot a projekt egyik .editorconfig fájljához:
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType
Jegyzet
Cserélje le a XXXXCAXXXX részét a vonatkozó szabály azonosítójára.
Engedélyezett szimbólumnévformátumok a beállításértékben (a következővel |elválasztva):
- Csak típusnév (a névvel rendelkező összes típust tartalmazza, függetlenül attól, hogy milyen típust vagy névteret tartalmaz).
- A szimbólum dokumentációazonosító formátumában található teljesen minősített nevek, opcionális
T:előtaggal.
Példák:
| Beállítás értéke | Összegzés |
|---|---|
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType |
Megfelel az összes névvel ellátott MyType típusnak és az összes származtatott típusnak. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 |
Megfelel minden olyan típusnak, amelyik vagy a MyType1 vagy a MyType2 nevet viseli, és az összes belőlük származtatott típusnak. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType |
Az adott MyType típust egyezteti a megadott teljes névvel és az összes származtatott típusával. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 |
Az MyType1 és MyType2 konkrét típusokat és azoknak a teljes kvalifikált neveket, valamint az összes származtatott típust egyezteti. |
Példák pszeudokódokra
Szabálysértés 1
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 Binders
{
public static SerializationBinder BookRecord =
new BookRecordSerializationBinder();
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(byte[] bytes)
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Binder = Binders.BookRecord;
using (MemoryStream ms = new MemoryStream(bytes))
{
return (BookRecord)formatter.Deserialize(ms); // CA2302 violation
}
}
}
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 Binders
Public Shared Property BookRecord As SerializationBinder = New BookRecordSerializationBinder()
End Class
Public Class ExampleClass
Public Function DeserializeBookRecord(bytes As Byte()) As BookRecord
Dim formatter As BinaryFormatter = New BinaryFormatter()
formatter.Binder = Binders.BookRecord
Using ms As MemoryStream = New MemoryStream(bytes)
Return CType(formatter.Deserialize(ms), BookRecord) ' CA2302 violation
End Using
End Function
End Class
1\. megoldás
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 Binders
{
public static SerializationBinder BookRecord =
new BookRecordSerializationBinder();
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(byte[] bytes)
{
BinaryFormatter formatter = new BinaryFormatter();
// Ensure that Binder is always non-null before deserializing
formatter.Binder = Binders.BookRecord ?? throw new Exception("Expected non-null binder");
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 Binders
Public Shared Property BookRecord As SerializationBinder = New BookRecordSerializationBinder()
End Class
Public Class ExampleClass
Public Function DeserializeBookRecord(bytes As Byte()) As BookRecord
Dim formatter As BinaryFormatter = New BinaryFormatter()
' Ensure that Binder is always non-null before deserializing
formatter.Binder = If(Binders.BookRecord, New Exception("Expected non-null"))
Using ms As MemoryStream = New MemoryStream(bytes)
Return CType(formatter.Deserialize(ms), BookRecord)
End Using
End Function
End Class
2. szabálysértés
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 BinaryFormatter Formatter { get; set; }
public BookRecord DeserializeBookRecord(byte[] bytes)
{
using (MemoryStream ms = new MemoryStream(bytes))
{
return (BookRecord) this.Formatter.Deserialize(ms); // CA2302 violation
}
}
}
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 Property Formatter As BinaryFormatter
Public Function DeserializeBookRecord(bytes As Byte()) As BookRecord
Using ms As MemoryStream = New MemoryStream(bytes)
Return CType(Me.Formatter.Deserialize(ms), BookRecord) ' CA2302 violation
End Using
End Function
End Class
2\. megoldás
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