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
, ,sbyte
char
,byte
, ,short
,int
SqlChars
SqlByte
SqlBytes
SqlBoolean
SqlDateTime
string
SqlDouble
TimeSpan
long
ulong
float
uint
double
ushort
decimal
Guid
SqlBinary
DateTime
DateTimeOffset
SqlDecimal
, ,SqlInt64
SqlInt32
SqlGuid
SqlInt16
,SqlMoney
en .SqlSingle
SqlString
- Veelgebruikte niet-primitieven:
Type
,Uri
enBigInteger
. - Veelgebruikte System.Drawing-typen:
Color
, ,PointF
Point
,Rectangle
,RectangleF
, , enSize
SizeF
. 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 DataTable
kolom 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 DataTable
te 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 alle DataSet
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.CustomType
toe 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 DataSet
DataTable
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.AllowArbitraryDataSetTypeInstantiation
wanneer 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 deDataAdapter.Fill
methode wordt gebruikt om eenDataSet
databasequery te vullen met de inhoud van een databasequery. - De
DataSet.ReadXml
ofDataTable.ReadXml
methode wordt gebruikt om een XML-bestand met kolom- en rijgegevens te lezen. - Een
DataSet
ofDataTable
exemplaar wordt geserialiseerd als onderdeel van een ASP.NET -webservices (SOAP) of WCF-eindpunt. - Een serialisatiefunctie, zoals
XmlSerializer
wordt gebruikt om eenDataSet
ofDataTable
meer exemplaren van een XML-stroom te deserialiseren. - Een serialisatiefunctie zoals
JsonConvert
wordt gebruikt om eenDataSet
ofDataTable
exemplaar van een JSON-stroom te deserialiseren.JsonConvert
is een methode in de populaire Newtonsoft.Json-bibliotheek van derden. - Een serializer zoals
BinaryFormatter
wordt gebruikt om eenDataSet
ofDataTable
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 SoapFormatter
NetDataContractSerializer
BinaryFormatter
om 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
ofDataTable
via een .asmx SOAP-eindpunt of een WCF-eindpunt. - Niet-vertrouwde gegevens deserialiseren in een exemplaar van
DataSet
ofDataTable
.
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