Share via


CA2330: Zorg ervoor dat JsonSerializer een beveiligde configuratie heeft bij het deserialiseren

Eigenschappen Weergegeven als
Regel-id CA2330
Titel Zorg ervoor dat JsonSerializer een beveiligde configuratie heeft bij het deserialiseren
Categorie Beveiliging
Oplossing is brekend of niet-brekend Niet-brekend
Standaard ingeschakeld in .NET 8 Nee

Oorzaak

Deze regel wordt geactiveerd wanneer aan beide van de volgende voorwaarden kan worden voldaan voor een Newtonsoft.Json.JsonSerializer-exemplaar dat wordt doorgegeven aan een deserialisatiemethode of geïnitialiseerd als een veld of eigenschap:

Deze regel is vergelijkbaar met CA2329, maar in dit geval kan analyse niet definitief bepalen of de serializer onveilig is geconfigureerd.

Deze regel analyseert standaard de hele codebasis, maar dit kan worden geconfigureerd.

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.

Deze regel vindt Newtonsoft.Json.Json.JsonSerializer-exemplaren die kunnen worden geconfigureerd voor het deserialiseren van typen die zijn opgegeven op basis van invoer, maar kunnen niet worden geconfigureerd om gedeserialiseerde typen te beperken met een Newtonsoft.Json.Serialization.ISerializationBinder. Als u deserialisatie van typen die zijn opgegeven vanuit invoer volledig wilt weigeren, schakelt u regels CA2327, CA2328, CA2329 en CA2330 uit en schakelt u in plaats daarvan regel CA2326 in.

Schendingen oplossen

Wanneer waarschuwingen onderdrukken

Het is veilig om een waarschuwing van deze regel te onderdrukken als:

Een waarschuwing onderdrukken

Als u slechts één schending wilt onderdrukken, voegt u preprocessorrichtlijnen toe aan uw bronbestand om de regel uit te schakelen en vervolgens opnieuw in te schakelen.

#pragma warning disable CA2330
// The code that's violating the rule is on this line.
#pragma warning restore CA2330

Als u de regel voor een bestand, map of project wilt uitschakelen, stelt u de ernst none ervan in op het configuratiebestand.

[*.{cs,vb}]
dotnet_diagnostic.CA2330.severity = none

Zie Codeanalysewaarschuwingen onderdrukken voor meer informatie.

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 MyTypetypen, 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 en N: 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 MyType1MyType2.
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 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

Oplossing

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

CA2326: Gebruik geen TypeNameHandling-waarden dan Geen

CA2327: Gebruik geen onveilige JsonSerializer Instellingen

CA2328: Zorg ervoor dat JsonSerializer Instellingen veilig zijn

CA2329: Niet deserialiseren met JsonSerializer met behulp van een onveilige configuratie