Share via


Beveiligingsrichtlijnen voor DataSet en DataTable

Dit artikel is van toepassing op:

  • .NET Framework (alle versies)
  • .NET Core en hoger
  • .NET 5 en hoger

De typen DataSet en DataTable zijn verouderde .NET-onderdelen waarmee gegevenssets als beheerde objecten kunnen worden weergegeven. Deze onderdelen zijn geïntroduceerd in .NET Framework 1.0 als onderdeel van de oorspronkelijke ADO.NET-infrastructuur. Het doel was om een beheerde weergave te bieden van een relationele gegevensset, waarbij de onderliggende bron van de gegevens XML, SQL of een andere technologie was.

Zie de documentatie over ADO.NET voor meer informatie over ADO.NET, waaronder modernere paradigma's voor gegevensweergaven.

Standaardbeperkingen bij het deserialiseren van een DataSet of DataTable vanuit XML

In alle ondersteunde versies van .NET Framework, .NET Core en .NET DataSet , en DataTable plaatst u de volgende beperkingen op welke typen objecten aanwezig kunnen zijn in de gedeserialiseerde gegevens. Deze lijst is standaard beperkt tot:

  • Primitieven en primitieve equivalenten: bool, , sbytechar, byte, , short, intSqlCharsSqlByteSqlBytesSqlBooleanSqlDateTimestringSqlDoubleTimeSpanlongulongfloatuintdoubleushortdecimalGuidSqlBinaryDateTimeDateTimeOffsetSqlDecimal, , SqlInt64SqlInt32SqlGuidSqlInt16, SqlMoneyen . SqlSingleSqlString
  • Veelgebruikte niet-primitieven: Type, Urien BigInteger.
  • Veelgebruikte System.Drawing-typen: Color, , PointFPoint, Rectangle, RectangleF, , en SizeSizeF.
  • Enum Typen.
  • Matrices en lijsten van de bovenstaande typen.

Als de binnenkomende XML-gegevens een object bevatten waarvan het type zich niet in deze lijst bevindt:

  • Er wordt een uitzondering gegenereerd met het volgende bericht en stacktracering. Foutbericht: System.InvalidOperationException: Typ '<Type Name>, Version=<n.n.n.n>, Culture=<culture>, PublicKeyToken=<token value>' is hier niet toegestaan. Stack Trace: at System.Data.TypeLimiter.EnsureTypeIsAllowed(Type, TypeLimiter capturedLimiter) at System.Data.DataColumn.UpdateColumnType(Type, StorageType typeCode) at System.Data.DataColumn.set_DataType(Type value)

  • De deserialisatiebewerking mislukt.

Bij het laden van XML in een bestaand DataSet exemplaar worden DataTable ook rekening gehouden met de bestaande kolomdefinities. Als de tabel al een kolomdefinitie van een aangepast type bevat, wordt dat type tijdelijk toegevoegd aan de acceptatielijst voor de duur van de XML-deserialisatiebewerking.

Notitie

Zodra u kolommen aan een DataTablekolom toevoegt, ReadXml wordt het schema niet gelezen uit de XML en als het schema niet overeenkomt, wordt het ook niet gelezen in de records, dus moet u alle kolommen zelf toevoegen om deze methode te gebruiken.

XmlReader xmlReader = GetXmlReader();

// Assume the XML blob contains data for type MyCustomClass.
// The following call to ReadXml fails because MyCustomClass isn't in the allowed types list.

DataTable table = new DataTable("MyDataTable");
table.ReadXml(xmlReader);

// However, the following call to ReadXml succeeds, since the DataTable instance
// already defines a column of type MyCustomClass.

DataTable table = new DataTable("MyDataTable");
table.Columns.Add("MyColumn", typeof(MyCustomClass));
table.ReadXml(xmlReader); // this call will succeed

De objecttypebeperkingen zijn ook van toepassing bij het XmlSerializer deserialiseren van een exemplaar van DataSet of DataTable. Ze kunnen echter niet van toepassing zijn wanneer ze worden gebruikt BinaryFormatter om een instantie van DataSet of DataTablete deserialiseren.

De beperkingen voor objecttypen zijn niet van toepassing bij gebruik DataAdapter.Fill, zoals wanneer een DataTable exemplaar rechtstreeks vanuit een database wordt gevuld zonder de XML-deserialisatie-API's te gebruiken.

De lijst met toegestane typen uitbreiden

Een app kan de lijst met toegestane typen uitbreiden met aangepaste typen, naast de hierboven genoemde ingebouwde typen. Als de lijst met toegestane typen wordt uitgebreid, is de wijziging van invloed op alleDataSet exemplaren DataTable in de app. Typen kunnen niet worden verwijderd uit de ingebouwde lijst met toegestane typen.

Uitbreiden via configuratie (.NET Framework 4.0 en hoger)

App.config kan worden gebruikt om de lijst met toegestane typen uit te breiden. De lijst met toegestane typen uitbreiden:

  • Gebruik het <configSections> element om een verwijzing naar de sectie System.Data-configuratie toe te voegen.
  • Gebruik <system.data.dataset.serialization>/<allowedTypes> dit om extra typen op te geven.

Elk <add> element moet slechts één type opgeven met behulp van de naam van het gekwalificeerde assemblytype. Als u extra typen wilt toevoegen aan de lijst met toegestane typen, gebruikt u meerdere <add> elementen.

In het volgende voorbeeld ziet u hoe u de lijst met toegestane typen uitbreidt door het aangepaste type Fabrikam.CustomTypetoe te voegen.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="system.data.dataset.serialization" type="System.Data.SerializationSettingsSectionGroup, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="allowedTypes" type="System.Data.AllowedTypesSectionHandler, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </sectionGroup>
  </configSections>
  <system.data.dataset.serialization>
    <allowedTypes>
      <!-- <add type="assembly qualified type name" /> -->
      <add type="Fabrikam.CustomType, Fabrikam, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2b3831f2f2b744f7" />
      <!-- additional <add /> elements as needed -->
    </allowedTypes>
  </system.data.dataset.serialization>
</configuration>

Als u de gekwalificeerde assemblynaam van een type wilt ophalen, gebruikt u de eigenschap Type.AssemblyQualifiedName , zoals wordt weergegeven in de volgende code.

string assemblyQualifiedName = typeof(Fabrikam.CustomType).AssemblyQualifiedName;

Uitbreiden via configuratie (.NET Framework 2.0 - 3.5)

Als uw app is gericht op .NET Framework 2.0 of 3.5, kunt u nog steeds het bovenstaande Mechanisme app.config gebruiken om de lijst met toegestane typen uit te breiden. Uw <configSections> element ziet er echter iets anders uit, zoals wordt weergegeven in de volgende code:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <!-- The below <sectionGroup> and <section> are specific to .NET Framework 2.0 and 3.5. -->
    <sectionGroup name="system.data.dataset.serialization" type="System.Data.SerializationSettingsSectionGroup, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="allowedTypes" type="System.Data.AllowedTypesSectionHandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </sectionGroup>
  </configSections>
  <system.data.dataset.serialization>
    <allowedTypes>
      <!-- <add /> elements, as demonstrated in the .NET Framework 4.0 - 4.8 sample code above. -->
    </allowedTypes>
  </system.data.dataset.serialization>
</configuration>

Programmatisch uitbreiden (.NET Framework, .NET Core, .NET 5+)

De lijst met toegestane typen kan ook programmatisch worden uitgebreid met behulp van AppDomain.SetData met de bekende sleutel System.Data.DataSetDefaultAllowedTypes, zoals wordt weergegeven in de volgende code.

Type[] extraAllowedTypes = new Type[]
{
    typeof(Fabrikam.CustomType),
    typeof(Contoso.AdditionalCustomType)
};

AppDomain.CurrentDomain.SetData("System.Data.DataSetDefaultAllowedTypes", extraAllowedTypes);

Als u het extensiemechanisme gebruikt, moet de waarde die is gekoppeld aan de sleutel System.Data.DataSetDefaultAllowedTypes van het type Type[]zijn.

In .NET Framework kan de lijst met toegestane typen worden uitgebreid, zowel met App.config als AppDomain.SetData. In dit geval DataSetDataTable kan een object worden gedeserialiseerd als onderdeel van de gegevens als het type aanwezig is in een van beide lijsten.

Een app uitvoeren in de auditmodus (.NET Framework)

Geef in .NET Framework DataSet een DataTable controlemodusmogelijkheid op. Wanneer de controlemodus is ingeschakeld DataSet en DataTable de typen binnenkomende objecten vergelijkt met de lijst met toegestane typen. Als echter een object waarvan het type niet is toegestaan, wordt er geen uitzondering gegenereerd. Stel DataTable in plaats DataSet daarvan eventuele gekoppelde TraceListener exemplaren op de hoogte dat er een verdacht type aanwezig is, zodat deze TraceListener informatie kan worden vastgelegd. Er wordt geen uitzondering gegenereerd en de deserialisatiebewerking wordt voortgezet.

Waarschuwing

Het uitvoeren van een app in de controlemodus mag alleen een tijdelijke meting zijn die wordt gebruikt voor het testen. Wanneer de controlemodus is ingeschakeld DataSet en DataTable geen typebeperkingen afdwingt, waardoor er een beveiligingsgat in uw app kan optreden. Zie de secties getiteld Alle typebeperkingen en Veiligheid verwijderen met betrekking tot niet-vertrouwde invoer voor meer informatie.

De controlemodus kan worden ingeschakeld via App.config:

  • Zie de sectie Uitbreiden via configuratie in dit document voor informatie over de juiste waarde voor het <configSections> element.
  • Gebruik <allowedTypes auditOnly="true"> dit om de controlemodus in te schakelen, zoals wordt weergegeven in de volgende markeringen.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <!-- See the section of this document titled "Extending through configuration" for the appropriate
         <sectionGroup> and <section> elements to put here, depending on whether you're running .NET
         Framework 2.0 - 3.5 or 4.0 - 4.8. -->
  </configSections>
  <system.data.dataset.serialization>
    <allowedTypes auditOnly="true"> <!-- setting auditOnly="true" enables audit mode -->
      <!-- Optional <add /> elements as needed. -->
    </allowedTypes>
  </system.data.dataset.serialization>
</configuration>

Zodra de controlemodus is ingeschakeld, kunt u App.config gebruiken om uw voorkeur TraceListener te verbinden met de DataSet ingebouwde TraceSource. naam van de ingebouwde traceringsbron System.Data.DataSet. In het volgende voorbeeld ziet u hoe traceringsgebeurtenissen naar de console en naar een logboekbestand op schijf worden geschreven.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.Data.DataSet"
              switchType="System.Diagnostics.SourceSwitch"
              switchValue="Warning">
        <listeners>
          <!-- write to the console -->
          <add name="console"
               type="System.Diagnostics.ConsoleTraceListener" />
          <!-- *and* write to a log file on disk -->
          <add name="filelog"
               type="System.Diagnostics.TextWriterTraceListener"
               initializeData="c:\logs\mylog.txt" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>

Zie het document Procedure: TraceSource en filters gebruiken met traceerlisteners voor meer informatie TraceSource over enTraceListener.

Notitie

Het uitvoeren van een app in de controlemodus is niet beschikbaar in .NET Core of in .NET 5 en hoger.

Alle typebeperkingen verwijderen

Als een app alle beperkingen voor het beperken van typen moet verwijderen van DataSet en DataTable:

  • Er zijn verschillende opties om beperkingen voor het beperken van typen te onderdrukken.
  • De beschikbare opties zijn afhankelijk van het framework dat de app-doelen hebben.

Waarschuwing

Als u alle typebeperkingen verwijdert, kan er een beveiligingsgat in de app worden geïntroduceerd. Wanneer u dit mechanisme gebruikt, moet u ervoor zorgen dat de app geen niet-vertrouwde invoer gebruikt DataSet of DataTable leest. Zie CVE-2020-1147 en de volgende sectie getiteld Veiligheid met betrekking tot niet-vertrouwde invoer voor meer informatie.

Via AppContext-configuratie (.NET Framework 4.6 en hoger, .NET Core 2.1 en hoger, .NET 5 en hoger)

De AppContext schakeloptie, Switch.System.Data.AllowArbitraryDataSetTypeInstantiationwanneer deze optie is ingesteld op true het verwijderen van alle beperkingen voor het beperken van typen van DataSet en DataTable.

In .NET Framework kan deze switch worden ingeschakeld via App.config, zoals wordt weergegeven in de volgende configuratie:

<configuration>
   <runtime>
      <!-- Warning: setting the following switch can introduce a security problem. -->
      <AppContextSwitchOverrides value="Switch.System.Data.AllowArbitraryDataSetTypeInstantiation=true" />
   </runtime>
</configuration>

In ASP.NET is het <AppContextSwitchOverrides> element niet beschikbaar. In plaats daarvan kan de switch worden ingeschakeld via Web.config, zoals wordt weergegeven in de volgende configuratie:

<configuration>
    <appSettings>
        <!-- Warning: setting the following switch can introduce a security problem. -->
        <add key="AppContext.SetSwitch:Switch.System.Data.AllowArbitraryDataSetTypeInstantiation" value="true" />
    </appSettings>
</configuration>

Zie het <element AppContextSwitchOverrides> voor meer informatie.

In .NET Core, .NET 5 en ASP.NET Core wordt deze instelling beheerd door runtimeconfig.json, zoals wordt weergegeven in de volgende JSON:

{
  "runtimeOptions": {
    "configProperties": {
      "Switch.System.Data.AllowArbitraryDataSetTypeInstantiation": true
    }
  }
}

Zie '.NET Core Runtime-configuratie-instellingen' voor meer informatie.

AllowArbitraryDataSetTypeInstantiation kan ook programmatisch worden ingesteld via AppContext.SetSwitch in plaats van een configuratiebestand te gebruiken, zoals wordt weergegeven in de volgende code:

// Warning: setting the following switch can introduce a security problem.
AppContext.SetSwitch("Switch.System.Data.AllowArbitraryDataSetTypeInstantiation", true);

Als u de voorgaande programmatische benadering kiest, moet de aanroep vroeg AppContext.SetSwitch in het opstarten van de apps plaatsvinden.

Via het computerbrede register (.NET Framework 2.0 - 4.x)

Als AppContext dit niet beschikbaar is, kunnen controles voor typebeperking worden uitgeschakeld met het Windows-register:

  • Een beheerder moet het register configureren.
  • Het gebruik van het register is een wijziging in de hele machine en is van invloed op alle apps die op de computer worden uitgevoerd.
Type Weergegeven als
Registersleutel HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext
Waardenaam Switch.System.Data.AllowArbitraryDataSetTypeInstantiation
Waardetype REG_SZ
Waardegegevens true

Op een 64-bits besturingssysteem moet deze waarde worden toegevoegd voor zowel de 64-bits sleutel (hierboven) als de 32-bits sleutel. De 32-bits sleutel bevindt zich op HKLM\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\AppContext.

Zie AppContext voor bibliotheekgebruikers voor meer informatie over het gebruik van het register dat u wilt configurerenAppContext.

Veiligheid met betrekking tot niet-vertrouwde invoer

Hoewel DataSet en DataTable er standaardbeperkingen gelden voor de typen die aanwezig mogen zijn tijdens het deserialiseren van XML-nettoladingen, DataSet en DataTable zijn ze in het algemeen niet veilig wanneer ze worden gevuld met niet-vertrouwde invoer. Hier volgt een niet-volledige lijst met manieren waarop een DataSet of DataTable exemplaar niet-vertrouwde invoer kan lezen.

  • Een DataAdapter verwijzing naar een database en de DataAdapter.Fill methode wordt gebruikt om een DataSet databasequery te vullen met de inhoud van een databasequery.
  • De DataSet.ReadXml of DataTable.ReadXml methode wordt gebruikt om een XML-bestand met kolom- en rijgegevens te lezen.
  • Een DataSet of DataTable exemplaar wordt geserialiseerd als onderdeel van een ASP.NET -webservices (SOAP) of WCF-eindpunt.
  • Een serialisatiefunctie, zoals XmlSerializer wordt gebruikt om een DataSet of DataTable meer exemplaren van een XML-stroom te deserialiseren.
  • Een serialisatiefunctie zoals JsonConvert wordt gebruikt om een DataSet of DataTable exemplaar van een JSON-stroom te deserialiseren. JsonConvertis een methode in de populaire Newtonsoft.Json-bibliotheek van derden.
  • Een serializer zoals BinaryFormatter wordt gebruikt om een DataSet of DataTable exemplaar van een onbewerkte bytestroom te deserialiseren.

In dit document worden veiligheidsoverwegingen voor de voorgaande scenario's besproken.

Gebruiken DataAdapter.Fill om een DataSet gegevensbron te vullen vanuit een niet-vertrouwde gegevensbron

Een DataSet exemplaar kan worden ingevuld vanuit een DataAdapter met behulp van de DataAdapter.Fill methode, zoals wordt weergegeven in het volgende voorbeeld.

// Assumes that connection is a valid SqlConnection object.
string queryString =
  "SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);

DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");

(Het bovenstaande codevoorbeeld maakt deel uit van een groter voorbeeld op Een DataSet uit een DataAdapter vullen.)

De meeste apps kunnen vereenvoudigen en ervan uitgaan dat hun databaselaag wordt vertrouwd. Als u echter gewend bent aan bedreigingsmodellering van uw apps, kan uw bedreigingsmodel er rekening mee houden dat er een vertrouwensgrens is tussen de toepassing (client) en de databaselaag (server). Het gebruik van wederzijdse verificatie of AAD-verificatie tussen client en server is een manier om de risico's te verhelpen die hieraan zijn gekoppeld. In de rest van deze sectie wordt het mogelijke resultaat besproken van een client die verbinding maakt met een niet-vertrouwde server.

De gevolgen van een verwijzing naar een DataAdapter niet-vertrouwde gegevensbron zijn afhankelijk van de implementatie van het DataAdapter zelf.

SqlDataAdapter

Voor het ingebouwde type SqlDataAdapter kan het verwijzen naar een niet-vertrouwde gegevensbron leiden tot een DoS-aanval (Denial of Service). De DoS-aanval kan ertoe leiden dat de app niet meer reageert of crasht. Als een aanvaller naast de app een DLL kan installeren, kan deze mogelijk ook lokale code uitvoeren.

Andere DataAdapter-typen

Implementaties van derden moeten hun eigen beoordelingen maken over de beveiligingsgaranties die ze bieden ten aanzien van niet-vertrouwde DataAdapter invoer. .NET kan geen veiligheidsgaranties met betrekking tot deze implementaties maken.

DataSet.ReadXml en DataTable.ReadXml

De DataSet.ReadXml methoden en DataTable.ReadXml methoden zijn niet veilig wanneer ze worden gebruikt met niet-vertrouwde invoer. We raden consumenten ten zeerste aan een van de alternatieven te gebruiken die verderop in dit document worden beschreven.

De implementaties van DataSet.ReadXml en DataTable.ReadXml zijn oorspronkelijk gemaakt voordat serialisatieproblemen een goed begrepen bedreigingscategorie waren. Als gevolg hiervan volgt de code niet de huidige aanbevolen beveiligingsprocedures. Deze API's kunnen worden gebruikt als vectoren voor aanvallers om DoS-aanvallen uit te voeren op web-apps. Deze aanvallen kunnen ertoe leiden dat de webservice niet meer reageert of leidt tot onverwachte procesafbreking. Het framework biedt geen oplossingen voor deze aanvalscategorieën en .NET beschouwt dit gedrag 'standaard'.

.NET heeft beveiligingsupdates uitgebracht om bepaalde problemen zoals openbaarmaking van informatie of uitvoering van externe code in DataSet.ReadXml en DataTable.ReadXml. De .NET-beveiligingsupdates bieden mogelijk geen volledige beveiliging tegen deze bedreigingscategorieën. Consumenten moeten hun individuele scenario's beoordelen en hun potentiële blootstelling aan deze risico's overwegen.

Consumenten moeten zich ervan bewust zijn dat beveiligingsupdates voor deze API's in sommige situaties van invloed kunnen zijn op de compatibiliteit van toepassingen. Bovendien bestaat de mogelijkheid dat er een nieuw beveiligingsprobleem in deze API's wordt gedetecteerd waarvoor .NET praktisch geen beveiligingsupdate kan publiceren.

We raden gebruikers van deze API's aan:

  • Overweeg een van de alternatieven te gebruiken die verderop in dit document worden beschreven.
  • Individuele risicobeoordelingen uitvoeren op hun apps.

Het is de enige verantwoordelijkheid van de consument om te bepalen of deze API's moeten worden gebruikt. Consumenten moeten alle beveiligings-, technische en juridische risico's beoordelen, met inbegrip van wettelijke vereisten, die bij het gebruik van deze API's kunnen horen.

DataSet en DataTable via ASP.NET webservices of WCF

Het is mogelijk om een DataSet of een DataTable exemplaar in een SOAP-webservice (ASP.NET) te accepteren, zoals wordt gedemonstreerd in de volgende code:

using System.Data;
using System.Web.Services;

[WebService(Namespace = "http://contoso.com/")]
public class MyService : WebService
{
    [WebMethod]
    public string MyWebMethod(DataTable dataTable)
    {
        /* Web method implementation. */
    }
}

Een variatie hierop is niet om te accepteren DataSet of DataTable rechtstreeks als parameter, maar in plaats daarvan als onderdeel van de algemene soap geserialiseerde objectgrafiek, zoals wordt weergegeven in de volgende code:

using System.Data;
using System.Web.Services;

[WebService(Namespace = "http://contoso.com/")]
public class MyService : WebService
{
    [WebMethod]
    public string MyWebMethod(MyClass data)
    {
        /* Web method implementation. */
    }
}

public class MyClass
{
    // Property of type DataTable, automatically serialized and
    // deserialized as part of the overall MyClass payload.
    public DataTable MyDataTable { get; set; }
}

Of gebruik WCF in plaats van ASP.NET webservices:

using System.Data;
using System.ServiceModel;

[ServiceContract(Namespace = "http://contoso.com/")]
public interface IMyContract
{
    [OperationContract]
    string MyMethod(DataTable dataTable);
    [OperationContract]
    string MyOtherMethod(MyClass data);
}

public class MyClass
{
    // Property of type DataTable, automatically serialized and
    // deserialized as part of the overall MyClass payload.
    public DataTable MyDataTable { get; set; }
}

In al deze gevallen zijn het bedreigingsmodel en de beveiligingsgaranties hetzelfde als de sectie DataSet.ReadXml en DataTable.ReadXml.

Een dataset of gegevenstabel deserialiseren via XmlSerializer

Ontwikkelaars kunnen deze gebruiken XmlSerializer om deserialiseren en DataTable exemplaren te deserialiserenDataSet, zoals wordt weergegeven in de volgende code:

using System.Data;
using System.IO;
using System.Xml.Serialization;

public DataSet PerformDeserialization1(Stream stream) {
    XmlSerializer serializer = new XmlSerializer(typeof(DataSet));
    return (DataSet)serializer.Deserialize(stream);
}

public MyClass PerformDeserialization2(Stream stream) {
    XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
    return (MyClass)serializer.Deserialize(stream);
}

public class MyClass
{
    // Property of type DataTable, automatically serialized and
    // deserialized as part of the overall MyClass payload.
    public DataTable MyDataTable { get; set; }
}

In deze gevallen zijn het bedreigingsmodel en de beveiligingsgaranties hetzelfde als de sectie DataSet.ReadXml en DataTable.ReadXml

Een dataset of gegevenstabel deserialiseren via JsonConvert

De populaire Newtonsoft-bibliotheek van derden Json.NET kan worden gebruikt om deserialiseren en DataTable exemplaren te deserialiserenDataSet, zoals wordt weergegeven in de volgende code:

using System.Data;
using Newtonsoft.Json;

public DataSet PerformDeserialization1(string json) {
    return JsonConvert.DeserializeObject<DataSet>(data);
}

public MyClass PerformDeserialization2(string json) {
    return JsonConvert.DeserializeObject<MyClass>(data);
}

public class MyClass
{
    // Property of type DataTable, automatically serialized and
    // deserialized as part of the overall MyClass payload.
    public DataTable MyDataTable { get; set; }
}

Het deserialiseren van een DataSet of DataTable op deze manier vanuit een niet-vertrouwde JSON-blob is niet veilig. Dit patroon is kwetsbaar voor een Denial of Service-aanval. Een dergelijke aanval kan de app vastlopen of deze niet meer reageren.

Notitie

Microsoft garandeert of ondersteunt de implementatie van bibliotheken van derden, zoals Newtonsoft.Json, niet. Deze informatie wordt volledigheid verstrekt en is nauwkeurig vanaf het moment van schrijven.

Een dataset of gegevenstabel deserialiseren via BinaryFormatter

U moet nooit onveilige formatters of gerelateerde onveilige formatters gebruiken SoapFormatterNetDataContractSerializerBinaryFormatterom een DataSet of DataTable exemplaar te deserialiseren vanaf een niet-vertrouwde nettolading:

  • Dit is vatbaar voor een volledige aanval op uitvoering van externe code.
  • Het gebruik van een aangepaste SerializationBinder functie is niet voldoende om een dergelijke aanval te voorkomen.

Veilige vervangingen

Voor apps die:

  • Accepteer DataSet of DataTable via een .asmx SOAP-eindpunt of een WCF-eindpunt.
  • Niet-vertrouwde gegevens deserialiseren in een exemplaar van DataSet of DataTable.

Overweeg het objectmodel te vervangen om Entity Framework te gebruiken. Entity Framework:

  • Is een uitgebreid, modern, objectgeoriënteerd framework dat relationele gegevens kan vertegenwoordigen.
  • Hiermee beschikt u over een divers ecosysteem van databaseproviders, zodat u eenvoudig databasequery's kunt projecteren via uw Entity Framework-objectmodellen.
  • Biedt ingebouwde beveiligingen bij het deserialiseren van gegevens uit niet-vertrouwde bronnen.

Voor apps die SOAP-eindpunten gebruiken .aspx , kunt u overwegen deze eindpunten te wijzigen voor het gebruik van WCF. WCF is een meer aanbevolen vervanging voor .asmx webservices. WCF-eindpunten kunnen worden weergegeven via SOAP voor compatibiliteit met bestaande bellers.

Codeanalyses

Code analyzer-beveiligingsregels, die worden uitgevoerd wanneer uw broncode wordt gecompileerd, kunnen helpen bij het vinden van beveiligingsproblemen met betrekking tot dit beveiligingsprobleem in C# en Visual Basic-code. Microsoft.CodeAnalysis.FxCopAnalyzers is een NuGet-pakket met codeanalyses die worden gedistribueerd op nuget.org.

Zie Overzicht van broncodeanalyses voor een overzicht van codeanalyses.

Schakel de volgende regels voor Microsoft.CodeAnalysis.FxCopAnalyzers in:

  • CA2350: DataTable.ReadXml() niet gebruiken met niet-vertrouwde gegevens
  • CA2351: DataSet.ReadXml() niet gebruiken met niet-vertrouwde gegevens
  • CA2352: Onveilige gegevensset of gegevenstabel in serializeerbaar type kan kwetsbaar zijn voor aanvallen op uitvoering van externe code
  • CA2353: Onveilige gegevensset of gegevenstabel in serialiseerbare type
  • CA2354: Onveilige gegevensset of gegevenstabel in deserialized objectgrafiek kan kwetsbaar zijn voor aanvallen op uitvoering van externe code
  • CA2355: Onveilige gegevensset of gegevenstabeltype gevonden in deserialisatiebare objectgrafiek
  • CA2356: Onveilige gegevensset of gegevenstabeltype in grafiek met webdeserialisatiebare objecten
  • CA2361: Ervoor zorgen dat automatisch gegenereerde klasse met DataSet.ReadXml() niet wordt gebruikt met niet-vertrouwde gegevens
  • CA2362: Onveilige gegevensset of gegevenstabel in automatisch gegenereerd serializeerbaar type kan kwetsbaar zijn voor aanvallen op uitvoering van externe code

Zie Code analyzers gebruiken voor meer informatie over het configureren van regels.

De nieuwe beveiligingsregels zijn beschikbaar in de volgende NuGet-pakketten:

  • Microsoft.CodeAnalysis.FxCopAnalyzers 3.3.0: voor Visual Studio 2019 versie 16.3 of hoger
  • Microsoft.CodeAnalysis.FxCopAnalyzers 2.9.11: voor Visual Studio 2017 versie 15.9 of hoger