Wskazówki dotyczące zabezpieczeń zestawów danych i tabeli DataTable
Ten artykuł dotyczy:
- .NET Framework (wszystkie wersje)
- .NET Core i nowsze wersje
- .NET 5 lub nowszy
Typy DataSet i DataTable to starsze składniki platformy .NET, które umożliwiają reprezentowanie zestawów danych jako obiektów zarządzanych. Te składniki zostały wprowadzone w programie .NET Framework 1.0 w ramach oryginalnej infrastruktury ADO.NET. Ich celem było zapewnienie zarządzanego widoku dla zestawu danych relacyjnych, abstrakcja, czy bazowe źródło danych to XML, SQL, czy inna technologia.
Aby uzyskać więcej informacji na temat ADO.NET, w tym bardziej nowoczesnych paradygmatów widoku danych, zobacz dokumentację ADO.NET.
Ograniczenia domyślne podczas deserializacji elementu DataSet lub DataTable z pliku XML
We wszystkich obsługiwanych wersjach programu .NET Framework, .NET Core i .NET DataSet
należy DataTable
umieścić następujące ograniczenia dotyczące typów obiektów, które mogą znajdować się w deserializacji danych. Domyślnie ta lista jest ograniczona do:
- Odpowiedniki pierwotne i pierwotne:
bool
, ,char
SqlInt32
sbyte
decimal
double
float
ulong
DateTime
long
uint
int
DateTimeOffset
ushort
short
byte
TimeSpan
string
SqlChars
SqlBytes
SqlDateTime
SqlByte
SqlDecimal
SqlBoolean
SqlDouble
SqlGuid
SqlBinary
Guid
SqlInt64
SqlMoney
SqlInt16
SqlSingle
i .SqlString
- Często używane nietypowe:
Type
,Uri
iBigInteger
. - Często używane typy System.Drawing:
Color
, ,Point
,Rectangle
PointF
,RectangleF
,Size
, iSizeF
. Enum
Typy.- Tablice i listy powyższych typów.
Jeśli przychodzące dane XML zawierają obiekt, którego typ nie znajduje się na tej liście:
Zgłaszany jest wyjątek z następującym komunikatem i śladem stosu. Komunikat o błędzie: System.InvalidOperationException: typ "<Nazwa> typu, Version=<n.n.n>., Culture=<culture>, PublicKeyToken=<token value>" nie jest dozwolony w tym miejscu. Ślad stosu: at System.Data.TypeLimiter.EnsureTypeIsAllowed(Type, TypeLimiter capturedLimiter) at System.Data.DataColumn.UpdateColumnType(Type, StorageType TypeCode) w System.Data.DataColumn.set_DataType(wartość typu)
Operacja deserializacji kończy się niepowodzeniem.
Podczas ładowania kodu XML do istniejącego DataSet
DataTable
wystąpienia uwzględniane są również istniejące definicje kolumn. Jeśli tabela zawiera już definicję kolumny typu niestandardowego, ten typ jest tymczasowo dodawany do listy dozwolonych na czas trwania operacji deserializacji XML.
Uwaga
Po dodaniu kolumn do DataTable
ReadXml
elementu element nie odczytuje schematu z pliku XML, a jeśli schemat nie jest zgodny, nie będzie również odczytywany w rekordach, dlatego należy dodać wszystkie kolumny samodzielnie, aby użyć tej metody.
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
Ograniczenia typu obiektu mają zastosowanie również w przypadku używania XmlSerializer
w celu deserializacji wystąpienia klasy DataSet
lub DataTable
. Mogą jednak nie mieć zastosowania w przypadku używania BinaryFormatter
funkcji do deserializacji wystąpienia klasy DataSet
lub DataTable
.
Ograniczenia typu obiektu nie mają zastosowania w przypadku używania elementu DataAdapter.Fill
, na przykład gdy DataTable
wystąpienie jest wypełniane bezpośrednio z bazy danych bez używania interfejsów API deserializacji XML.
Rozszerzanie listy dozwolonych typów
Aplikacja może rozszerzyć listę dozwolonych typów, aby uwzględnić typy niestandardowe oprócz wbudowanych typów wymienionych powyżej. W przypadku rozszerzania listy dozwolonych typów zmiana ma wpływ na wszystkie DataSet
wystąpienia i DataTable
w aplikacji. Nie można usunąć typów z listy typów wbudowanych dozwolonych.
Rozszerzanie konfiguracji (.NET Framework 4.0 i nowsze)
Plik App.config może służyć do rozszerzania listy dozwolonych typów. Aby rozszerzyć listę dozwolonych typów:
- Użyj elementu ,
<configSections>
aby dodać odwołanie do sekcji Konfiguracji System.Data . - Użyj
<system.data.dataset.serialization>
/<allowedTypes>
polecenia , aby określić dodatkowe typy.
Każdy <add>
element musi określać tylko jeden typ przy użyciu nazwy kwalifikowanego typu zestawu. Aby dodać dodatkowe typy do listy dozwolonych typów, użyj wielu <add>
elementów.
W poniższym przykładzie pokazano rozszerzenie listy dozwolonych typów przez dodanie typu Fabrikam.CustomType
niestandardowego .
<?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>
Aby pobrać kwalifikowaną nazwę zestawu typu, użyj właściwości Type.AssemblyQualifiedName , jak pokazano w poniższym kodzie.
string assemblyQualifiedName = typeof(Fabrikam.CustomType).AssemblyQualifiedName;
Rozszerzanie konfiguracji (.NET Framework 2.0 – 3.5)
Jeśli aplikacja jest przeznaczona dla programu .NET Framework 2.0 lub 3.5, nadal możesz użyć powyższego mechanizmu App.config , aby rozszerzyć listę dozwolonych typów. Jednak element <configSections>
będzie wyglądać nieco inaczej, jak pokazano w poniższym kodzie:
<?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>
Programowe rozszerzanie (.NET Framework, .NET Core, .NET 5+)
Listę dozwolonych typów można również rozszerzyć programowo przy użyciu parametru AppDomain.SetData z dobrze znanym kluczem System.Data.DataSetDefaultAllowedTypes, jak pokazano w poniższym kodzie.
Type[] extraAllowedTypes = new Type[]
{
typeof(Fabrikam.CustomType),
typeof(Contoso.AdditionalCustomType)
};
AppDomain.CurrentDomain.SetData("System.Data.DataSetDefaultAllowedTypes", extraAllowedTypes);
W przypadku korzystania z mechanizmu rozszerzenia wartość skojarzona z kluczem System.Data.DataSetDefaultAllowedTypes musi być typu Type[]
.
W programie .NET Framework lista dozwolonych typów może zostać rozszerzona zarówno przy użyciu pliku App.config , jak i AppDomain.SetData
. W takim przypadku obiekt DataTable
będzie deserializowany jako część danych, DataSet
jeśli jego typ znajduje się na obu listach.
Uruchamianie aplikacji w trybie inspekcji (.NET Framework)
W programie .NET Framework DataSet
i DataTable
zapewniają możliwość trybu inspekcji. Gdy tryb inspekcji jest włączony, DataSet
i DataTable
porównaj typy obiektów przychodzących z listy dozwolonych typów. Jeśli jednak obiekt, którego typ jest niedozwolony, nie zostanie zgłoszony wyjątek. Zamiast tego należy DataTable
powiadomić wszystkie dołączone TraceListener
wystąpienia o tym, DataSet
że istnieje podejrzany typ, co umożliwi TraceListener
rejestrowanie tych informacji. Nie jest zgłaszany wyjątek, a operacja deserializacji jest kontynuowana.
Ostrzeżenie
Uruchamianie aplikacji w trybie inspekcji powinno być tylko tymczasową miarą używaną do testowania. Gdy tryb inspekcji jest włączony DataSet
i DataTable
nie wymuszaj ograniczeń typu, które mogą wprowadzać dziurę zabezpieczeń wewnątrz aplikacji. Aby uzyskać więcej informacji, zobacz sekcje zatytułowane Usuwanie wszystkich ograniczeń typu i Bezpieczeństwo w odniesieniu do niezaufanych danych wejściowych.
Tryb inspekcji można włączyć za pomocą pliku App.config:
- Zobacz sekcję Rozszerzanie konfiguracji w tym dokumencie, aby uzyskać informacje na temat odpowiedniej wartości, która ma być umieszczona
<configSections>
dla elementu. - Użyj
<allowedTypes auditOnly="true">
polecenia , aby włączyć tryb inspekcji, jak pokazano w poniższym znaczniku.
<?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>
Po włączeniu trybu inspekcji możesz użyć pliku App.config, aby połączyć DataSet
TraceListener
preferowaną z wbudowanym TraceSource.
nazwą wbudowanego źródła śledzenia jest System.Data.DataSet. W poniższym przykładzie pokazano zapisywanie zdarzeń śledzenia w konsoli programu i pliku dziennika na dysku.
<?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>
Aby uzyskać więcej informacji na temat TraceSource
elementów i TraceListener
, zobacz dokument Instrukcje: używanie elementu TraceSource i filtrów z odbiornikami śledzenia.
Uwaga
Uruchamianie aplikacji w trybie inspekcji nie jest dostępne na platformie .NET Core lub w programie .NET 5 lub nowszym.
Usuń wszystkie ograniczenia typu
Jeśli aplikacja musi usunąć wszystkie ograniczenia ograniczania typów z DataSet
i DataTable
:
- Istnieje kilka opcji pomijania ograniczeń ograniczania typów.
- Dostępne opcje zależą od struktury docelowej aplikacji.
Ostrzeżenie
Usunięcie wszystkich ograniczeń typu może wprowadzić dziurę zabezpieczeń wewnątrz aplikacji. W przypadku korzystania z tego mechanizmu upewnij się, że aplikacja nie używa DataSet
ani DataTable
nie odczytuje niezaufanych danych wejściowych. Aby uzyskać więcej informacji, zobacz CVE-2020-1147 i następującą sekcję zatytułowaną Bezpieczeństwo w odniesieniu do niezaufanych danych wejściowych.
Za pomocą konfiguracji aplikacji AppContext (program .NET Framework 4.6 lub nowszy, .NET Core 2.1 i nowsze wersje, .NET 5 i nowsze)
Przełącznik AppContext
, Switch.System.Data.AllowArbitraryDataSetTypeInstantiation
po ustawieniu na wartość true
, usuwa wszystkie ograniczenia ograniczania typów z DataSet
i DataTable
.
W programie .NET Framework ten przełącznik można włączyć za pośrednictwem pliku App.config, jak pokazano w następującej konfiguracji:
<configuration>
<runtime>
<!-- Warning: setting the following switch can introduce a security problem. -->
<AppContextSwitchOverrides value="Switch.System.Data.AllowArbitraryDataSetTypeInstantiation=true" />
</runtime>
</configuration>
W ASP.NET <AppContextSwitchOverrides>
element jest niedostępny. Zamiast tego przełącznik można włączyć za pośrednictwem pliku Web.config, jak pokazano w następującej konfiguracji:
<configuration>
<appSettings>
<!-- Warning: setting the following switch can introduce a security problem. -->
<add key="AppContext.SetSwitch:Switch.System.Data.AllowArbitraryDataSetTypeInstantiation" value="true" />
</appSettings>
</configuration>
Aby uzyskać więcej informacji, zobacz element AppContextSwitchOverrides>.<
W programie .NET Core, .NET 5 i ASP.NET Core to ustawienie jest kontrolowane przez runtimeconfig.json, jak pokazano w następującym formacie JSON:
{
"runtimeOptions": {
"configProperties": {
"Switch.System.Data.AllowArbitraryDataSetTypeInstantiation": true
}
}
}
Aby uzyskać więcej informacji, zobacz ".NET Core runtime configuration settings" (Ustawienia konfiguracji środowiska uruchomieniowego platformy .NET Core).
AllowArbitraryDataSetTypeInstantiation
Można również ustawić programowo za pomocą pliku konfiguracji AppContext.SetSwitch , jak pokazano w poniższym kodzie:
// Warning: setting the following switch can introduce a security problem.
AppContext.SetSwitch("Switch.System.Data.AllowArbitraryDataSetTypeInstantiation", true);
W przypadku wybrania powyższego podejścia programowego wywołanie AppContext.SetSwitch
powinno nastąpić na wczesnym etapie uruchamiania aplikacji.
Za pośrednictwem rejestru całego komputera (.NET Framework 2.0 – 4.x)
Jeśli AppContext
nie jest dostępna, kontrole ograniczania typów można wyłączyć w rejestrze systemu Windows:
- Administrator musi skonfigurować rejestr.
- Korzystanie z rejestru jest zmianą dla całej maszyny i będzie miało wpływ na wszystkie aplikacje uruchomione na maszynie.
Type | Wartość |
---|---|
Klucz rejestru | HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext |
Nazwa wartości | Switch.System.Data.AllowArbitraryDataSetTypeInstantiation |
Typ wartości | REG_SZ |
Dane wartości | true |
W 64-bitowym systemie operacyjnym należy dodać tę wartość dla 64-bitowego klucza (pokazanego powyżej) i 32-bitowego klucza. Klucz 32-bitowy znajduje się w lokalizacji HKLM\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\AppContext
.
Aby uzyskać więcej informacji na temat konfigurowania AppContext
rejestru, zobacz "AppContext dla użytkowników biblioteki".
Bezpieczeństwo w odniesieniu do niezaufanych danych wejściowych
Chociaż DataSet
i DataTable
nakładają domyślne ograniczenia dotyczące typów, które mogą być obecne podczas deserializacji ładunków XML, DataSet
i DataTable
są ogólnie nie bezpieczne, gdy są wypełniane niezaufanymi danymi wejściowymi. Poniżej znajduje się niewyczerpująca lista sposobów odczytywania DataSet
niezaufanych danych wejściowych przez wystąpienie lub DataTable
.
- Obiekt
DataAdapter
odwołuje się do bazy danych, aDataAdapter.Fill
metoda służy do wypełnianiaDataSet
obiektu zawartością zapytania bazy danych. - Metoda
DataSet.ReadXml
orDataTable.ReadXml
służy do odczytywania pliku XML zawierającego informacje o kolumnie i wierszu. - Wystąpienie
DataSet
lubDataTable
jest serializowane w ramach usług internetowych ASP.NET (SOAP) lub punktu końcowego programu WCF. - Serializator, taki jak
XmlSerializer
, służy do deserializacjiDataSet
wystąpienia lubDataTable
ze strumienia XML. - Serializator, taki jak
JsonConvert
, służy do deserializacjiDataSet
wystąpienia lubDataTable
ze strumienia JSON.JsonConvert
jest metodą w popularnej bibliotece Newtonsoft.Json innej firmy. - Serializator, taki jak
BinaryFormatter
, służy do deserializacjiDataSet
wystąpienia lubDataTable
z nieprzetworzonego strumienia bajtów.
W tym dokumencie omówiono zagadnienia dotyczące bezpieczeństwa w poprzednich scenariuszach.
Użyj DataAdapter.Fill
polecenia , aby wypełnić element DataSet
z niezaufanego źródła danych
Wystąpienie DataSet
można wypełnić DataAdapter
przy użyciu DataAdapter.Fill
metody , jak pokazano w poniższym przykładzie.
// 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");
(Powyższy przykład kodu jest częścią większej próbki znalezionej w Wypełnianie elementu DataSet z elementu DataAdapter).
Większość aplikacji może uprościć i zakładać, że ich warstwa bazy danych jest zaufana. Jeśli jednak jesteś w zwyczaju modelowania zagrożeń w aplikacjach, model zagrożenia może rozważyć granicę zaufania między aplikacją (klientem) i warstwą bazy danych (serwer). Korzystanie z wzajemnego uwierzytelniania lub uwierzytelniania usługi AAD między klientem a serwerem jest jednym ze sposobów rozwiązywania problemów związanych z tym ryzykiem. W pozostałej części tej sekcji omówiono możliwy wynik połączenia klienta z niezaufanym serwerem.
Konsekwencje wskazywania DataAdapter
elementu w niezaufanym źródle danych zależą od implementacji DataAdapter
samego źródła danych.
SqlDataAdapter
W przypadku wbudowanego typu SqlDataAdapter odwołanie do niezaufanego źródła danych może spowodować atak typu "odmowa usługi" (DoS). Atak DoS może spowodować, że aplikacja nie odpowiada lub ulega awarii. Jeśli osoba atakująca może umieścić bibliotekę DLL obok aplikacji, może również być w stanie osiągnąć lokalne wykonywanie kodu.
Inne typy dataAdapter
Implementacje innych firm DataAdapter
muszą dokonać własnych ocen dotyczących gwarancji bezpieczeństwa, jakie zapewniają w obliczu niezaufanych danych wejściowych. Platforma .NET nie może zagwarantować bezpieczeństwa tych implementacji.
DataSet.ReadXml i DataTable.ReadXml
Metody DataSet.ReadXml
i DataTable.ReadXml
nie są bezpieczne w przypadku użycia z niezaufanymi danymi wejściowymi. Zdecydowanie zalecamy, aby konsumenci zamiast tego rozważyli użycie jednej z alternatyw opisanych w dalszej części tego dokumentu.
Implementacje DataSet.ReadXml
elementów i DataTable.ReadXml
zostały pierwotnie utworzone przed serializacji lukami w zabezpieczeniach były dobrze zrozumiałą kategorią zagrożeń. W związku z tym kod nie stosuje bieżących najlepszych rozwiązań w zakresie zabezpieczeń. Te interfejsy API mogą służyć jako wektory do przeprowadzania ataków typu DoS na aplikacje internetowe. Te ataki mogą spowodować brak odpowiedzi usługi internetowej lub spowodować nieoczekiwane zakończenie procesu. Struktura nie zapewnia środków zaradczych dla tych kategorii ataków, a platforma .NET uważa to zachowanie za "według projektu".
Platforma .NET opublikowała aktualizacje zabezpieczeń, aby rozwiązać niektóre problemy, takie jak ujawnienie informacji lub zdalne wykonywanie kodu w usługach DataSet.ReadXml
i DataTable.ReadXml
. Aktualizacje zabezpieczeń platformy .NET mogą nie zapewnić pełnej ochrony przed tymi kategoriami zagrożeń. Konsumenci powinni ocenić swoje indywidualne scenariusze i rozważyć potencjalne narażenie na te zagrożenia.
Użytkownicy powinni pamiętać, że aktualizacje zabezpieczeń tych interfejsów API mogą mieć wpływ na zgodność aplikacji w niektórych sytuacjach. Ponadto istnieje możliwość wykrycia nowej luki w zabezpieczeniach tych interfejsów API, dla której platforma .NET nie może praktycznie opublikować aktualizacji zabezpieczeń.
Zalecamy, aby użytkownicy tych interfejsów API:
- Rozważ użycie jednej z alternatyw opisanych w dalszej części tego dokumentu.
- Przeprowadzanie indywidualnych ocen ryzyka w aplikacjach.
Jedynym zadaniem konsumenta jest określenie, czy korzystać z tych interfejsów API. Konsumenci powinni ocenić wszelkie zagrożenia bezpieczeństwa, techniczne i prawne, w tym wymagania prawne, które mogą towarzyszyć przy użyciu tych interfejsów API.
Zestaw danych i dataTable za pośrednictwem usług internetowych ASP.NET lub WCF
Istnieje możliwość zaakceptowania DataSet
wystąpienia lub DataTable
w usłudze internetowej ASP.NET (SOAP), jak pokazano w poniższym kodzie:
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. */
}
}
Odmiana tego nie jest akceptowana DataSet
lub DataTable
bezpośrednio jako parametr, ale zamiast tego akceptowana jako część ogólnego grafu obiektów serializowanego protokołu SOAP, jak pokazano w poniższym kodzie:
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; }
}
Możesz też użyć programu WCF zamiast ASP.NET usług internetowych:
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; }
}
We wszystkich tych przypadkach model zagrożeń i gwarancje zabezpieczeń są takie same jak w sekcji DataSet.ReadXml i DataTable.ReadXml.
Deserializowanie elementu DataSet lub DataTable za pomocą elementu XmlSerializer
Deweloperzy mogą używać XmlSerializer
do deserializacji DataSet
i DataTable
wystąpień, jak pokazano w poniższym kodzie:
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; }
}
W takich przypadkach model zagrożeń i gwarancje bezpieczeństwa są takie same jak sekcja DataSet.ReadXml i DataTable.ReadXml
Deserializowanie elementu DataSet lub DataTable za pomocą pliku JsonConvert
Popularna biblioteka Newtonsoft innej firmy Json.NET może służyć do deserializacji DataSet
i DataTable
wystąpień, jak pokazano w poniższym kodzie:
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; }
}
Deserializowanie obiektu DataSet
blob JSON lub DataTable
w ten sposób nie jest bezpieczne. Ten wzorzec jest podatny na atak typu "odmowa usługi". Taki atak może spowodować awarię aplikacji lub uniemożliwić jej działanie.
Uwaga
Firma Microsoft nie gwarantuje ani nie obsługuje implementacji bibliotek innych firm, takich jak Newtonsoft.Json. Te informacje są dostarczane do kompletności i są dokładne w czasie pisania.
Deserializowanie elementu DataSet lub DataTable za pomocą elementu BinaryFormatter
Do deserializacji wystąpienia lub z niezaufanego ładunku nigdy nie należy używać BinaryFormatter
plików , SoapFormatter
NetDataContractSerializer
, ani powiązanych niebezpiecznych formatów:DataTable
DataSet
- Jest to podatne na atak pełnego zdalnego wykonywania kodu.
- Użycie niestandardowego
SerializationBinder
elementu nie jest wystarczające, aby zapobiec takiemu atakowi.
Bezpieczne wymiany
W przypadku aplikacji, które:
- Zaakceptuj
DataSet
lubDataTable
za pośrednictwem punktu końcowego protokołu SOAP asmx lub punktu końcowego programu WCF. - Deserializowanie niezaufanych danych w wystąpieniu
DataSet
klasy lubDataTable
.
Rozważ zastąpienie modelu obiektów do używania programu Entity Framework. Entity Framework:
- To bogata, nowoczesna, zorientowana na obiekt struktura, która może reprezentować dane relacyjne.
- Oferuje zróżnicowany ekosystem dostawców baz danych, aby ułatwić projektowanie zapytań bazy danych za pośrednictwem modeli obiektów programu Entity Framework.
- Oferuje wbudowane zabezpieczenia podczas deserializacji danych z niezaufanych źródeł.
W przypadku aplikacji korzystających z .aspx
punktów końcowych protokołu SOAP rozważ zmianę tych punktów końcowych w celu korzystania z usługi WCF. WCF to bardziej w pełni funkcjonalna zamiana .asmx
usług internetowych. Punkty końcowe programu WCF można uwidocznić za pośrednictwem protokołu SOAP w celu zachowania zgodności z istniejącymi obiektami wywołującymi.
Analizatory kodu
Reguły zabezpieczeń analizatora kodu, które są uruchamiane po skompilowaniu kodu źródłowego, mogą pomóc w znalezieniu luk w zabezpieczeniach związanych z tym problemem z zabezpieczeniami w kodzie C# i Visual Basic. Microsoft.CodeAnalysis.FxCopAnalyzers to pakiet NuGet analizatorów kodu dystrybuowanych na nuget.org.
Aby zapoznać się z omówieniem analizatorów kodu, zobacz Omówienie analizatorów kodu źródłowego.
Włącz następujące reguły Microsoft.CodeAnalysis.FxCopAnalyzers:
- CA2350: Nie używaj elementu DataTable.ReadXml() z niezaufanymi danymi
- CA2351: Nie używaj elementu DataSet.ReadXml() z niezaufanymi danymi
- CA2352: Niebezpieczny element DataSet lub DataTable w typie z możliwością serializacji może być narażony na ataki zdalnego wykonywania kodu
- CA2353: Niebezpieczny zestaw danych lub dataTable w typie z możliwością serializacji
- CA2354: Niebezpieczny element DataSet lub DataTable w deserializowanym grafie obiektu może być narażony na ataki zdalnego wykonywania kodu
- CA2355: Niebezpieczny typ DataSet lub DataTable znaleziony na grafie obiektów deserializowalnych
- CA2356: Niebezpieczny typ DataSet lub DataTable w internetowym deserializowalnym grafie obiektu
- CA2361: Upewnij się, że automatycznie wygenerowana klasa zawierająca klasę DataSet.ReadXml() nie jest używana z niezaufanymi danymi
- CA2362: Niebezpieczny element DataSet lub DataTable w automatycznie wygenerowanym typie serializowalnym może być narażony na ataki zdalnego wykonywania kodu
Aby uzyskać więcej informacji na temat konfigurowania reguł, zobacz Używanie analizatorów kodu.
Nowe reguły zabezpieczeń są dostępne w następujących pakietach NuGet:
- Microsoft.CodeAnalysis.FxCopAnalyzers 3.3.0: dla programu Visual Studio 2019 w wersji 16.3 lub nowszej
- Microsoft.CodeAnalysis.FxCopAnalyzers 2.9.11: dla programu Visual Studio 2017 w wersji 15.9 lub nowszej