CA2330: Seri durumdan çıkarırken JsonSerializer'ın güvenli bir yapılandırması olduğundan emin olun
Özellik | Değer |
---|---|
Kural Kimliği | CA2330 |
Başlık | Seri durumdan çıkarılırken JsonSerializer’ın güvenli bir yapılandırmaya sahip olmasını sağlayın |
Kategori | Güvenlik |
Hataya neden olan veya bozulmayan düzeltme | Hataya neden olmayan |
.NET 9'da varsayılan olarak etkin | Hayır |
Neden
Seri durumdan çıkarma yöntemine geçirilen veya alan veya özellik olarak başlatılan bir Newtonsoft.Json.JsonSerializer örneği için aşağıdaki koşulların her ikisi de doğru olduğunda bu kural tetiklenir:
- TypeNameHandling özelliği dışında
None
bir değerdir. - SerializationBinder özelliği null.
Bu kural CA2329'a benzer, ancak bu durumda çözümleme, seri hale getiricinin güvenli olmayan bir şekilde yapılandırılıp yapılandırılmadığını kesin olarak belirleyemez.
Varsayılan olarak, bu kural tüm kod tabanını analiz eder, ancak bu yapılandırılabilir.
Kural açıklaması
Güvenilmeyen verilerin seri durumdan çıkarılması sırasında güvenli olmayan seri durumdan çıkarıcılar savunmasızdır. Saldırgan, kötü amaçlı yan etkilere sahip nesneler eklemek için seri hale getirilmiş verileri beklenmeyen türler içerecek şekilde değiştirebilir. Güvenli olmayan bir seri durumdan çıkarıcıya yönelik bir saldırı, örneğin, temel işletim sisteminde komut yürütebilir, ağ üzerinden iletişim kurabilir veya dosyaları silebilir.
Bu kural, girişten belirtilen türleri seri durumdan çıkarmak üzere yapılandırılabilir ancak seri durumdan çıkarılmış türleri Newtonsoft.Json.Serialization.ISerializationBinder ile kısıtlanacak şekilde yapılandırılmayan Newtonsoft.Json.JsonSerializer örneklerini bulur. Girişten belirtilen türlerin seri durumdan çıkarılmasına tamamen izin vermek istemiyorsanız, CA2327, CA2328, CA2329 ve CA2330 kurallarını devre dışı bırakın ve bunun yerine CA2326 kuralını etkinleştirin.
İhlalleri düzeltme
- Mümkünse TypeNameHandling değerini
None
kullanın. - Serileştirilmiş verilerin kurcalanmaya karşı dayanıklı olmasını sağlayın. Serileştirmeden sonra, serileştirilmiş verileri şifreli olarak imzalayın. Seri durumdan çıkarmadan önce şifreleme imzasını doğrulayın. Şifreleme anahtarının açıklanmasını önleyip anahtar döndürmeleri için tasarım yapma.
- Seri durumdan çıkarılmış türleri kısıtlayın. Özel bir Newtonsoft.Json.Serialization.ISerializationBinder uygulayın. Json.NET ile seri durumdan çıkarmadan önce özel ISerializationBinder'ınızın Newtonsoft.Json.JsonSerializer.SerializationBinder özelliğinde belirtildiğinden emin olun. Geçersiz kılınan Newtonsoft.Json.Serialization.ISerializationBinder.BindToType yönteminde, tür beklenmeyense seri durumdan çıkarma işlemini durdurmak için bir özel durum döndür veya
null
oluştur.
Uyarıların ne zaman bastırılması gerekiyor?
Aşağıdakiler durumunda bu kuraldan gelen bir uyarıyı engellemek güvenlidir:
- Girişin güvenilir olduğunu biliyorsunuz. Uygulamanızın güven sınırının ve veri akışlarının zaman içinde değişebileceğini göz önünde bulundurun.
- İhlalleri düzeltme bölümünde yer alan önlemlerden birini aldıysanız.
- TypeNameHandling özelliği dışında
None
bir değer olduğunda Newtonsoft.Json.JsonSerializer.SerializationBinder özelliğinin her zaman ayarlandığını biliyorsunuz.
Uyarıyı gizleme
Yalnızca tek bir ihlali engellemek istiyorsanız, kuralı devre dışı bırakmak ve sonra yeniden etkinleştirmek için kaynak dosyanıza ön işlemci yönergeleri ekleyin.
#pragma warning disable CA2330
// The code that's violating the rule is on this line.
#pragma warning restore CA2330
Bir dosya, klasör veya projenin kuralını devre dışı bırakmak için, yapılandırma dosyasındaki önem derecesini none
olarak ayarlayın.
[*.{cs,vb}]
dotnet_diagnostic.CA2330.severity = none
Daha fazla bilgi için bkz . Kod analizi uyarılarını gizleme.
Çözümlemek için kod yapılandırma
Bu kuralın kod tabanınızın hangi bölümlerinde çalıştırılacaklarını yapılandırmak için aşağıdaki seçenekleri kullanın.
Bu seçenekleri yalnızca bu kural, geçerli olduğu tüm kurallar veya bu kategorideki (Güvenlik) tüm kurallar için yapılandırabilirsiniz. Daha fazla bilgi için bkz . Kod kalitesi kuralı yapılandırma seçenekleri.
Belirli simgeleri hariç tutma
Türler ve yöntemler gibi belirli simgeleri analizden hariç tutabilirsiniz. Örneğin, kuralın adlı MyType
türlerdeki herhangi bir kodda çalışmaması gerektiğini belirtmek için, projenizdeki bir .editorconfig dosyasına aşağıdaki anahtar-değer çiftini ekleyin:
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType
Seçenek değerinde izin verilen simge adı biçimleri (ile |
ayrılmış):
- Yalnızca sembol adı (içeren tür veya ad alanı ne olursa olsun, ada sahip tüm simgeleri içerir).
- Simgenin belge kimliği biçimindeki tam adlar. Her simge adı için yöntemler
T:
, türler veN:
ad alanları gibiM:
bir sembol türü ön eki gerekir. .ctor
oluşturucular ve.cctor
statik oluşturucular için.
Örnekler:
Seçenek Değeri | Özet |
---|---|
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType |
adlı MyType tüm simgelerle eşleşir. |
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 |
veya MyType2 adlı MyType1 tüm simgelerle eşleşir. |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) |
Belirtilen tam imza ile belirli bir yöntemi MyMethod eşleştirir. |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) |
Belirli yöntemlerle MyMethod1 ve MyMethod2 ilgili tam imzalarla eşleşir. |
Belirli türleri ve türetilmiş türlerini dışlama
Belirli türleri ve türetilmiş türlerini analizden dışlayabilirsiniz. Örneğin, kuralın adlı MyType
ve türetilmiş türleri içindeki hiçbir yöntemde çalışmaması gerektiğini belirtmek için, projenizdeki bir .editorconfig dosyasına aşağıdaki anahtar-değer çiftini ekleyin:
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType
Seçenek değerinde izin verilen simge adı biçimleri (ile |
ayrılmış):
- Yalnızca tür adı (içeren tür veya ad alanına bakılmaksızın adı olan tüm türleri içerir).
- Simgenin belge kimliği biçiminde, isteğe bağlı
T:
ön ek içeren tam adlar.
Örnekler:
Seçenek Değeri | Özet |
---|---|
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType |
Adlı MyType tüm türleri ve türetilmiş türlerinin tümünü eşleştirir. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 |
veya MyType2 adlı MyType1 tüm türleri ve türetilmiş türlerinin tümünü eşleştirir. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType |
Belirli bir türü MyType verilen tam adla ve türetilmiş tüm türleriyle eşleştirir. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 |
Belirli türleri MyType1 ve MyType2 ilgili tam adlarla ve bunların türetilmiş tüm türleriyle eşleşir. |
Sahte kod örnekleri
Ihlal
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public class BookRecordSerializationBinder : ISerializationBinder
{
// To maintain backwards compatibility with serialized data before using an ISerializationBinder.
private static readonly DefaultSerializationBinder Binder = new DefaultSerializationBinder();
public void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
Binder.BindToName(serializedType, out assemblyName, out typeName);
}
public Type BindToType(string assemblyName, string typeName)
{
// If the type isn't expected, then stop deserialization.
if (typeName != "BookRecord" && typeName != "AisleLocation" && typeName != "WarehouseLocation")
{
return null;
}
return Binder.BindToType(assemblyName, typeName);
}
}
public class BookRecord
{
public string Title { get; set; }
public object Location { get; set; }
}
public abstract class Location
{
public string StoreId { get; set; }
}
public class AisleLocation : Location
{
public char Aisle { get; set; }
public byte Shelf { get; set; }
}
public class WarehouseLocation : Location
{
public string Bay { get; set; }
public byte Shelf { get; set; }
}
public static class Binders
{
public static ISerializationBinder BookRecord = new BookRecordSerializationBinder();
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(JsonReader reader)
{
JsonSerializer jsonSerializer = new JsonSerializer();
jsonSerializer.TypeNameHandling = TypeNameHandling.Auto;
jsonSerializer.SerializationBinder = Binders.BookRecord;
return jsonSerializer.Deserialize<BookRecord>(reader); // CA2330 -- SerializationBinder might be null
}
}
Imports System
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Serialization
Public Class BookRecordSerializationBinder
Implements ISerializationBinder
' To maintain backwards compatibility with serialized data before using an ISerializationBinder.
Private Shared ReadOnly Property Binder As New DefaultSerializationBinder()
Public Sub BindToName(serializedType As Type, ByRef assemblyName As String, ByRef typeName As String) Implements ISerializationBinder.BindToName
Binder.BindToName(serializedType, assemblyName, typeName)
End Sub
Public Function BindToType(assemblyName As String, typeName As String) As Type Implements ISerializationBinder.BindToType
' If the type isn't expected, then stop deserialization.
If typeName <> "BookRecord" AndAlso typeName <> "AisleLocation" AndAlso typeName <> "WarehouseLocation" Then
Return Nothing
End If
Return Binder.BindToType(assemblyName, typeName)
End Function
End Class
Public Class BookRecord
Public Property Title As String
Public Property Location As Location
End Class
Public MustInherit Class Location
Public Property StoreId As String
End Class
Public Class AisleLocation
Inherits Location
Public Property Aisle As Char
Public Property Shelf As Byte
End Class
Public Class WarehouseLocation
Inherits Location
Public Property Bay As String
Public Property Shelf As Byte
End Class
Public Class Binders
Public Shared Property BookRecord As ISerializationBinder = New BookRecordSerializationBinder()
End Class
Public Class ExampleClass
Public Function DeserializeBookRecord(reader As JsonReader) As BookRecord
Dim jsonSerializer As JsonSerializer = New JsonSerializer()
jsonSerializer.TypeNameHandling = TypeNameHandling.Auto
jsonSerializer.SerializationBinder = Binders.BookRecord
Return jsonSerializer.Deserialize(Of BookRecord)(reader) ' CA2330 -- SerializationBinder might be null
End Function
End Class
Çözüm
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public class BookRecordSerializationBinder : ISerializationBinder
{
// To maintain backwards compatibility with serialized data before using an ISerializationBinder.
private static readonly DefaultSerializationBinder Binder = new DefaultSerializationBinder();
public void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
Binder.BindToName(serializedType, out assemblyName, out typeName);
}
public Type BindToType(string assemblyName, string typeName)
{
// If the type isn't expected, then stop deserialization.
if (typeName != "BookRecord" && typeName != "AisleLocation" && typeName != "WarehouseLocation")
{
return null;
}
return Binder.BindToType(assemblyName, typeName);
}
}
public class BookRecord
{
public string Title { get; set; }
public object Location { get; set; }
}
public abstract class Location
{
public string StoreId { get; set; }
}
public class AisleLocation : Location
{
public char Aisle { get; set; }
public byte Shelf { get; set; }
}
public class WarehouseLocation : Location
{
public string Bay { get; set; }
public byte Shelf { get; set; }
}
public static class Binders
{
public static ISerializationBinder BookRecord = new BookRecordSerializationBinder();
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(JsonReader reader)
{
JsonSerializer jsonSerializer = new JsonSerializer();
jsonSerializer.TypeNameHandling = TypeNameHandling.Auto;
// Ensure that SerializationBinder is assigned non-null before deserializing
jsonSerializer.SerializationBinder = Binders.BookRecord ?? throw new Exception("Expected non-null");
return jsonSerializer.Deserialize<BookRecord>(reader);
}
}
Imports System
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Serialization
Public Class BookRecordSerializationBinder
Implements ISerializationBinder
' To maintain backwards compatibility with serialized data before using an ISerializationBinder.
Private Shared ReadOnly Property Binder As New DefaultSerializationBinder()
Public Sub BindToName(serializedType As Type, ByRef assemblyName As String, ByRef typeName As String) Implements ISerializationBinder.BindToName
Binder.BindToName(serializedType, assemblyName, typeName)
End Sub
Public Function BindToType(assemblyName As String, typeName As String) As Type Implements ISerializationBinder.BindToType
' If the type isn't expected, then stop deserialization.
If typeName <> "BookRecord" AndAlso typeName <> "AisleLocation" AndAlso typeName <> "WarehouseLocation" Then
Return Nothing
End If
Return Binder.BindToType(assemblyName, typeName)
End Function
End Class
Public Class BookRecord
Public Property Title As String
Public Property Location As Location
End Class
Public MustInherit Class Location
Public Property StoreId As String
End Class
Public Class AisleLocation
Inherits Location
Public Property Aisle As Char
Public Property Shelf As Byte
End Class
Public Class WarehouseLocation
Inherits Location
Public Property Bay As String
Public Property Shelf As Byte
End Class
Public Class Binders
Public Shared Property BookRecord As ISerializationBinder = New BookRecordSerializationBinder()
End Class
Public Class ExampleClass
Public Function DeserializeBookRecord(reader As JsonReader) As BookRecord
Dim jsonSerializer As JsonSerializer = New JsonSerializer()
jsonSerializer.TypeNameHandling = TypeNameHandling.Auto
' Ensure SerializationBinder is non-null before deserializing
jsonSerializer.SerializationBinder = If(Binders.BookRecord, New Exception("Expected non-null"))
Return jsonSerializer.Deserialize(Of BookRecord)(reader)
End Function
End Class
İlgili kurallar
CA2326: TypeNameHandling değerlerini None dışında kullanmayın
CA2327: Güvenli olmayan JsonSerializerSettings kullanmayın
CA2328: JsonSerializerSettings'in güvenli olduğundan emin olun
CA2329: Güvenli olmayan bir yapılandırma kullanarak JsonSerializer ile seri durumdan çıkarma