CA2330: Upewnij się, że program JsonSerializer ma bezpieczną konfigurację podczas deserializacji
Właściwości | Wartość |
---|---|
Identyfikator reguły | CA2330 |
Tytuł | Upewnij się, że podczas deserializacji rozwiązania JsonSerializer ma bezpieczną konfigurację |
Kategoria | Bezpieczeństwo |
Poprawka powodująca niezgodność lub niezgodność | Niezgodność |
Domyślnie włączone na platformie .NET 9 | Nie. |
Przyczyna
Ta reguła jest uruchamiana, gdy oba następujące warunki mogą mieć wartość true dla wystąpienia Newtonsoft.Json.JsonSerializer , które jest przekazywane do metody deserializacji lub zainicjowane jako pole lub właściwość:
- Właściwość TypeNameHandling jest wartością inną niż
None
. - Właściwość SerializationBinder ma wartość null.
Ta reguła jest podobna do CA2329, ale w tym przypadku analiza nie może ostatecznie określić, czy serializator jest skonfigurowany niepewnie.
Domyślnie ta reguła analizuje całą bazę kodu, ale można to skonfigurować.
Opis reguły
Niezabezpieczone deserializatory są podatne na deserializacji niezaufanych danych. Osoba atakująca może zmodyfikować serializowane dane w celu uwzględnienia nieoczekiwanych typów w celu wstrzyknięcia obiektów ze złośliwymi skutkami ubocznymi. Atak na niezabezpieczonego deserializatora może na przykład wykonywać polecenia w bazowym systemie operacyjnym, komunikować się za pośrednictwem sieci lub usuwać pliki.
Ta reguła znajduje wystąpienia Newtonsoft.Json.JsonSerializer , które mogą być skonfigurowane do deserializacji typów określonych z danych wejściowych, ale nie można skonfigurować w celu ograniczenia deserializacji typów za pomocą polecenia Newtonsoft.Json.Serialization.ISerializationBinder. Jeśli chcesz całkowicie uniemożliwić deserializacji typów określonych z danych wejściowych, wyłącz reguły CA2327, CA2328, CA2329 i CA23330, a następnie włącz regułę CA2326.
Jak naprawić naruszenia
- Jeśli to możliwe, użyj wartości TypeNameHandling.
None
- Ustaw serializacji danych na dowód manipulacji. Po serializacji kryptograficznie podpisz serializowane dane. Przed deserializacji zweryfikuj podpis kryptograficzny. Ochrona klucza kryptograficznego przed ujawnieniem i projektowaniem rotacji kluczy.
- Ogranicz deserializowane typy. Zaimplementuj niestandardowy element Newtonsoft.Json.Serialization.ISerializationBinder. Przed deserializacji przy użyciu Json.NET upewnij się, że niestandardowa właściwość ISerializationBinder jest określona w właściwości Newtonsoft.Json.JsonSerializer.SerializationBinder . W zastąpieniu metody Newtonsoft.Json.Serialization.ISerializationBinder.BindToType , jeśli typ jest nieoczekiwany, zwróć
null
lub zgłosi wyjątek, aby zatrzymać deserializacji.
Kiedy pomijać ostrzeżenia
Można bezpiecznie pominąć ostrzeżenie z tej reguły, jeśli:
- Wiesz, że dane wejściowe są zaufane. Należy wziąć pod uwagę, że granica zaufania aplikacji i przepływy danych mogą ulec zmianie w czasie.
- Podjęto jeden z środków ostrożności w temacie Jak naprawić naruszenia.
- Wiesz, że właściwość Newtonsoft.Json.JsonSerializer.SerializationBinder jest zawsze ustawiana, gdy właściwość TypeNameHandling jest wartością inną niż
None
.
Pomijanie ostrzeżenia
Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.
#pragma warning disable CA2330
// The code that's violating the rule is on this line.
#pragma warning restore CA2330
Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none
w pliku konfiguracji.
[*.{cs,vb}]
dotnet_diagnostic.CA2330.severity = none
Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.
Konfigurowanie kodu do analizowania
Użyj poniższych opcji, aby skonfigurować, które części bazy kodu mają być uruchamiane w tej regule.
Możesz skonfigurować te opcje tylko dla tej reguły, dla wszystkich reguł, do których ma ona zastosowanie, lub dla wszystkich reguł w tej kategorii (Zabezpieczenia), których dotyczy. Aby uzyskać więcej informacji, zobacz Opcje konfiguracji reguły jakości kodu.
Wykluczanie określonych symboli
Z analizy można wykluczyć określone symbole, takie jak typy i metody. Aby na przykład określić, że reguła nie powinna być uruchamiana w żadnym kodzie w typach o nazwie MyType
, dodaj następującą parę klucz-wartość do pliku editorconfig w projekcie:
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType
Dozwolone formaty nazw symboli w wartości opcji (oddzielone przez |
):
- Tylko nazwa symbolu (zawiera wszystkie symbole o nazwie, niezależnie od typu zawierającego lub przestrzeni nazw).
- W pełni kwalifikowane nazwy w formacie identyfikatora dokumentacji symbolu. Każda nazwa symboli wymaga prefiksu typu symboli, takiego jak
M:
metody,T:
dla typów iN:
przestrzeni nazw. .ctor
dla konstruktorów i.cctor
konstruktorów statycznych.
Przykłady:
Wartość opcji | Podsumowanie |
---|---|
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType |
Pasuje do wszystkich symboli o nazwie MyType . |
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 |
Pasuje do wszystkich symboli o nazwie MyType1 lub MyType2 . |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) |
Pasuje do określonej metody MyMethod z określonym w pełni kwalifikowanym podpisem. |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) |
Pasuje do określonych metod MyMethod1 i MyMethod2 z odpowiednimi w pełni kwalifikowanymi podpisami. |
Wykluczanie określonych typów i ich typów pochodnych
Z analizy można wykluczyć określone typy i ich typy pochodne. Aby na przykład określić, że reguła nie powinna być uruchamiana na żadnych metodach w typach nazwanych MyType
i ich typach pochodnych, dodaj następującą parę klucz-wartość do pliku .editorconfig w projekcie:
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType
Dozwolone formaty nazw symboli w wartości opcji (oddzielone przez |
):
- Nazwa typu (zawiera tylko wszystkie typy o nazwie, niezależnie od typu zawierającego lub przestrzeni nazw).
- W pełni kwalifikowane nazwy w formacie identyfikatora dokumentacji symbolu z opcjonalnym
T:
prefiksem.
Przykłady:
Wartość opcji | Podsumowanie |
---|---|
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType |
Pasuje do wszystkich typów nazwanych MyType i wszystkich ich typów pochodnych. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 |
Dopasuje wszystkie typy o nazwie MyType1 lub MyType2 i wszystkie ich typy pochodne. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType |
Pasuje do określonego typu MyType z daną w pełni kwalifikowaną nazwą i wszystkimi jego typami pochodnymi. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 |
Pasuje do określonych typów MyType1 i MyType2 z odpowiednimi w pełni kwalifikowanymi nazwami i wszystkimi ich typami pochodnymi. |
Przykłady przykładów kodu przykładowego
Naruszenie
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
Rozwiązanie
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
Powiązane reguły
CA2326: Nie używaj wartości TypeNameHandling innych niż None
CA2327: Nie używaj niezabezpieczonych ustawień JsonSerializerSettings
CA2328: Upewnij się, że ustawienia JsonSerializerSettings są bezpieczne