Wskazówki dotyczące zabezpieczeń zestawów danych i DataTableDataSet and DataTable security guidance

Ten artykuł dotyczy następującego oprogramowania:This article applies to:

  • .NET Framework (wszystkie wersje).NET Framework (all versions)
  • .NET Core i nowsze.NET Core and later
  • .NET 5,0 i nowsze.NET 5.0 and later

Zestaw danych i typy DataTable są starszymi składnikami platformy .NET, które umożliwiają reprezentowania zestawów danych jako obiektów zarządzanych.The DataSet and DataTable types are legacy .NET components that allow representing data sets as managed objects. Te składniki zostały wprowadzone w .NET Framework 1,0 w ramach oryginalnej infrastruktury ADO.NET.These components were introduced in .NET Framework 1.0 as part of the original ADO.NET infrastructure. Ich celem było zapewnienie widoku zarządzanego na potrzeby relacyjnego zestawu danych, który jest bardziej abstrakcyjny, niezależnie od tego, czy bazowe źródło danych było XML, SQL czy inną technologią.Their goal was to provide a managed view over a relational data set, abstracting away whether the underlying source of the data was XML, SQL, or another technology.

Aby uzyskać więcej informacji na temat ADO.NET, w tym bardziej nowoczesnych odmian widoku danych, zapoznaj się z dokumentacją ADO.NET.For more information on ADO.NET, including more modern data view paradigms, see the ADO.NET documentation.

Domyślne ograniczenia podczas deserializacji zestawu danych lub elementu DataTable z pliku XMLDefault restrictions when deserializing a DataSet or DataTable from XML

We wszystkich obsługiwanych wersjach .NET Framework, .NET Core i .NET DataSet i należy DataTable wprowadzić następujące ograniczenia dotyczące typów obiektów, które mogą być obecne w deserializowanych danych.On all supported versions of .NET Framework, .NET Core, and .NET, DataSet and DataTable place the following restrictions on what types of objects may be present in the deserialized data. Domyślnie ta lista jest ograniczona do:By default, this list is restricted to:

  • Elementy podstawowe i równoważne podstawowe:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, bool char sbyte byte short ushort int uint long ulong float double decimal DateTime DateTimeOffset TimeSpan string Guid SqlBinary SqlBoolean SqlByte SqlBytes SqlChars SqlDateTime SqlDecimal SqlDouble SqlGuid SqlInt16 SqlInt32 SqlInt64 SqlMoney SqlSingle i SqlString .Primitives and primitive equivalents: bool, char, sbyte, byte, short, ushort, int, uint, long, ulong, float, double, decimal, DateTime, DateTimeOffset, TimeSpan, string, Guid, SqlBinary, SqlBoolean, SqlByte, SqlBytes, SqlChars, SqlDateTime, SqlDecimal, SqlDouble, SqlGuid, SqlInt16, SqlInt32, SqlInt64, SqlMoney, SqlSingle, and SqlString.
  • Często używane elementy inne niż pierwotne: Type , Uri , i BigInteger .Commonly used non-primitives: Type, Uri, and BigInteger.
  • Najczęściej używane typy System. Drawing : Color ,,,,, Point PointF Rectangle RectangleF Size i SizeF .Commonly used System.Drawing types: Color, Point, PointF, Rectangle, RectangleF, Size, and SizeF.
  • Enum Typ.Enum types.
  • Tablice i listy powyższych typów.Arrays and lists of the above types.

Jeśli dane przychodzące XML zawierają obiekt, którego typ nie znajduje się na tej liście:If the incoming XML data contains an object whose type is not in this list:

  • Wyjątek jest zgłaszany przy użyciu następującego komunikatu i śladu stosu.An exception is thrown with the following message and stack trace. Komunikat o błędzie: System. InvalidOperationException: Type " <Type Name> , Version = <n.n.n.n> , Culture = <culture> , PublicKeyToken = <token value> " jest niedozwolony w tym miejscu.Error Message: System.InvalidOperationException : Type '<Type Name>, Version=<n.n.n.n>, Culture=<culture>, PublicKeyToken=<token value>' is not allowed here. https://go.microsoft.com/fwlink/?linkid=2132227Aby uzyskać więcej informacji, zobacz.See https://go.microsoft.com/fwlink/?linkid=2132227 for more details. Ślad stosu: w System. Data. TypeLimiter. EnsureTypeIsAllowed (typ typu, TypeLimiter capturedLimiter) w System. Data. DataColumn. UpdateColumnType (typ typu, StorageType) w System.Data.DataColumn.set_DataType (wartość typu)Stack Trace: at System.Data.TypeLimiter.EnsureTypeIsAllowed(Type type, TypeLimiter capturedLimiter) at System.Data.DataColumn.UpdateColumnType(Type type, StorageType typeCode) at System.Data.DataColumn.set_DataType(Type value)

  • Operacja deserializacji kończy się niepowodzeniem.The deserialization operation fails.

Podczas ładowania kodu XML do istniejącego DataSet DataTable wystąpienia lub istniejące definicje kolumn są również brane pod uwagę.When loading XML into an existing DataSet or DataTable instance, the existing column definitions are also taken into account. Jeśli tabela zawiera już definicję kolumny typu niestandardowego, ten typ jest tymczasowo dodawany do listy dozwolonych w czasie trwania operacji deserializacji XML.If the table already contains a column definition of a custom type, that type is temporarily added to the allow list for the duration of the XML deserialization operation.

Uwaga

Po dodaniu kolumn do programu DataTable program ReadXml nie odczytuje schematu z kodu 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.Once you add columns to a DataTable, ReadXml will not read the schema from the XML, and if the schema does not match it will also not read in the records, so you will need to add all the columns yourself to use this method.

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 XmlSerializer deserializacji wystąpienia DataSet lub DataTable .The object type restrictions also apply when using XmlSerializer to deserialize an instance of DataSet or DataTable. Jednak mogą nie stosować BinaryFormatter się do deserializacji wystąpienia DataSet lub DataTable .However, they may not apply when using BinaryFormatter to deserialize an instance of DataSet or DataTable.

Ograniczenia dotyczące typu obiektu nie mają zastosowania, na przykład DataAdapter.Fill gdy DataTable wystąpienie jest wypełniane bezpośrednio z bazy danych bez użycia interfejsów API deserializacji XML.The object type restrictions don't apply when using DataAdapter.Fill, such as when a DataTable instance is populated directly from a database without using the XML deserialization APIs.

Rozwiń listę dozwolonych typówExtend the list of allowed types

Aplikacja może rozbudować listę dozwolonych typów, aby uwzględnić niestandardowe typy oprócz wbudowanych typów wymienionych powyżej.An app can extend the allowed types list to include custom types in addition to the built-in types listed above. Jeśli rozszerzasz listę dozwolonych typów, zmiana ma wpływ na wszystkie DataSet DataTable wystąpienia w aplikacji.If extending the allowed types list, the change affects all DataSet and DataTable instances within the app. Typów nie można usunąć z listy wbudowanych typów dozwolonych.Types cannot be removed from the built-in allowed types list.

Przechodzenie do konfiguracji (.NET Framework 4,0 – 4,8)Extend through configuration (.NET Framework 4.0 - 4.8)

App.config można użyć do rozszerania listy dozwolonych typów.App.config can be used to extend the allowed types list. Aby rozwinąć listę dozwolonych typów:To extend the allowed types list:

  • Użyj <configSections> elementu, aby dodać odwołanie do sekcji Konfiguracja System. Data .Use the <configSections> element to add a reference to the System.Data configuration section.
  • Użyj <system.data.dataset.serialization> / <allowedTypes> , aby określić dodatkowe typy.Use <system.data.dataset.serialization>/<allowedTypes> to specify additional types.

Każdy <add> element musi określać tylko jeden typ za pomocą nazwy typu kwalifikowanego zestawu.Each <add> element must specify only one type by using its assembly qualified type name. Aby dodać dodatkowe typy do listy dozwolonych typów, Użyj wielu <add> elementów.To add additional types to the allowed types list, use multiple <add> elements.

Poniższy przykład pokazuje Rozszerzanie listy dozwolonych typów przez dodanie typu niestandardowego Fabrikam.CustomType .The following sample shows extending the allowed types list by adding the custom type Fabrikam.CustomType.

<?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.To retrieve the assembly qualified name of a type, use the Type.AssemblyQualifiedName property, as demonstrated in the following code.

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

Przechodzenie do konfiguracji (.NET Framework 2,0 – 3,5)Extend through configuration (.NET Framework 2.0 - 3.5)

Jeśli aplikacja jest przeznaczona dla .NET Framework 2,0 lub 3,5, nadal możesz użyć powyższego mechanizmu App.config , aby rozwinąć listę dozwolonych typów.If your app targets .NET Framework 2.0 or 3.5, you can still use the above App.config mechanism to extend the allowed types list. Jednak <configSections> element będzie wyglądał nieco inaczej, jak pokazano w poniższym kodzie:However, your <configSections> element will look slightly different, as shown in the following 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>

Zwiększ programowo (.NET Framework, .NET Core, .NET 5.0 +)Extend programmatically (.NET Framework, .NET Core, .NET 5.0+)

Listę dozwolonych typów można również rozszerzyć programowo przy użyciu elementu AppDomain. SetData z dobrze znanym kluczem System. Data. DataSetDefaultAllowedTypes, jak pokazano w poniższym kodzie.The list of allowed types can also be extended programmatically by using AppDomain.SetData with the well-known key System.Data.DataSetDefaultAllowedTypes, as shown in the following code.

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

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

W przypadku używania mechanizmu rozszerzenia wartość skojarzona z kluczem System. Data. DataSetDefaultAllowedTypes musi być typu Type[] .If using the extension mechanism, the value associated with the key System.Data.DataSetDefaultAllowedTypes must be of type Type[].

Na .NET Framework lista dozwolonych typów może być rozszerzona zarówno z App.config , jak i AppDomain.SetData .On .NET Framework, the list of allowed types may be extended both with App.config and AppDomain.SetData. W tym przypadku DataSet i DataTable zezwoli na deserializacji obiektu w ramach danych, jeśli jego typ znajduje się na liście.In this case, DataSet and DataTable will allow an object to be deserialized as part of the data if its type is present in either list.

Uruchom aplikację w trybie inspekcji (.NET Framework)Run an app in audit mode (.NET Framework)

W .NET Framework DataSet i DataTable zapewniają możliwość trybu inspekcji.In .NET Framework, DataSet and DataTable provide an audit mode capability. Gdy tryb inspekcji jest włączony, DataSet należy DataTable porównać typy obiektów przychodzących z listą dozwolonych typów.When audit mode is enabled, DataSet and DataTable compare the types of incoming objects against the allowed types list. Jeśli jednak obiekt, którego typ jest niedozwolony, jest widoczny, wyjątek nie zostanie zgłoszony.However, if an object whose type is not allowed is seen, an exception is not thrown. Zamiast tego DataSet należy DataTable powiadomić wszystkie dołączone TraceListener wystąpienia o typie podejrzanym, co pozwala na TraceListener rejestrowanie tych informacji.Instead, DataSet and DataTable notify any attached TraceListener instances that a suspicious type is present, allowing the TraceListener to log this information. Nie jest zgłaszany żaden wyjątek, a operacja deserializacji będzie kontynuowana.No exception is thrown and the deserialization operation continues.

Ostrzeżenie

Uruchamianie aplikacji w trybie inspekcji powinna być tylko tymczasowym środkiem używanym do testowania.Running an app in "audit mode" should only be a temporary measure used for testing. Gdy tryb inspekcji jest włączony DataSet i DataTable nie Wymuszaj ograniczeń typu, co może spowodować powstanie sieci w aplikacji.When audit mode is enabled, DataSet and DataTable do not enforce type restrictions, which can introduce a security hole inside your app. Aby uzyskać więcej informacji, zobacz sekcje zatytułowane usuwanie wszystkich ograniczeń typu i bezpieczeństwo w odniesieniu do niezaufanych danych wejściowych.For more information, see the sections titled Removing all type restrictions and Safety with regard to untrusted input.

Tryb inspekcji można włączyć za App.config:Audit mode can be enabled through App.config:

  • Zapoznaj się z sekcją rozszerzanie przez konfigurację w tym dokumencie, aby uzyskać informacje na temat właściwej wartości do umieszczenia dla <configSections> elementu.See the Extending through configuration section in this document for information on the proper value to put for the <configSections> element.
  • Użyj <allowedTypes auditOnly="true"> , aby włączyć tryb inspekcji, jak pokazano w poniższej tabeli.Use <allowedTypes auditOnly="true"> to enable audit mode, as shown in the following markup.
<?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>

Gdy tryb inspekcji jest włączony, można użyć App.config , aby połączyć preferowaną z TraceListener DataSet wbudowaną nazwą wbudowanego TraceSource. źródła śledzenia jest System. Data. DataSet.Once audit mode is enabled, you can use App.config to connect your preferred TraceListener to the DataSet built-in TraceSource. The name of the built-in trace source is System.Data.DataSet. Poniższy przykład ilustruje zapisywanie zdarzeń śledzenia w konsoli programu i w pliku dziennika na dysku.The following sample demonstrates writing trace events to the console and to a log file on disk.

<?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 i TraceListener , zobacz dokument How to: use TraceSource and filters with Trace detektors.For more information on TraceSource and TraceListener, see the document How to: Use TraceSource and Filters with Trace Listeners.

Uwaga

Uruchamianie aplikacji w trybie inspekcji nie jest dostępne w programie .NET Core ani w programie .NET 5,0 i nowszych wersjach.Running an app in audit mode is not available in .NET Core or in .NET 5.0 and later.

Usuń wszystkie ograniczenia typówRemove all type restrictions

Jeśli aplikacja musi usunąć wszystkie ograniczenia dotyczące ograniczania typów z DataSet i DataTable :If an app must remove all type limiting restrictions from DataSet and DataTable:

  • Istnieje kilka opcji, aby pominąć ograniczenia ograniczające typy.There are several options to suppress type limiting restrictions.
  • Dostępne opcje zależą od struktury docelowej aplikacji.The options available depend on the framework the app targets.

Ostrzeżenie

Usunięcie wszystkich ograniczeń dotyczących typów może spowodować powstanie otworu zabezpieczeń wewnątrz aplikacji.Removing all type restrictions can introduce a security hole inside the app. W przypadku korzystania z tego mechanizmu upewnij się, że aplikacja nie używa lub nie DataSet DataTable odczytuje niezaufanych danych wejściowych.When using this mechanism, ensure the app does not use DataSet or DataTable to read untrusted input. Aby uzyskać więcej informacji, zobacz CVE-2020-1147 i w poniższej sekcji zatytułowanej bezpieczeństwo w odniesieniu do niezaufanych danych wejściowych.For more information, see CVE-2020-1147 and the following section titled Safety with regard to untrusted input.

Za poorednictwem konfiguracji AppContext (.NET Framework 4,6-4,8, .NET Core 2,1 i nowszych, .NET 5,0 i nowsze)Through AppContext configuration (.NET Framework 4.6 - 4.8, .NET Core 2.1 and later, .NET 5.0 and later)

AppContextPrzełącznik, Switch.System.Data.AllowArbitraryDataSetTypeInstantiation , po ustawieniu, aby true usunąć wszystkie ograniczenia dotyczące ograniczania typów z DataSet i DataTable .The AppContext switch, Switch.System.Data.AllowArbitraryDataSetTypeInstantiation, when set to true removes all type limiting restrictions from DataSet and DataTable.

W .NET Framework tego przełącznika można włączyć za pośrednictwem App.config, jak pokazano w następującej konfiguracji:In .NET Framework, this switch can be enabled via App.config, as shown in the following configuration:

<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 nie jest dostępny.In ASP.NET, the <AppContextSwitchOverrides> element is not available. Zamiast tego przełącznik można włączyć za pośrednictwem Web.config, jak pokazano w następującej konfiguracji:Instead, the switch can be enabled via Web.config, as shown in the following configuration:

<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 <AppContextSwitchOverrides> element.For more information, see the <AppContextSwitchOverrides> element.

W przypadku platformy .NET Core, .NET 5 i ASP.NET Core to ustawienie jest kontrolowane przez runtimeconfig.jsna, jak pokazano w poniższym kodzie JSON:In .NET Core, .NET 5, and ASP.NET Core, this setting is controlled by runtimeconfig.json, as shown in the following JSON:

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

Aby uzyskać więcej informacji, zobacz "podstawowe ustawienia konfiguracji środowiska uruchomieniowego .NET".For more information, see ".NET Core run-time configuration settings".

AllowArbitraryDataSetTypeInstantiation można również ustawić programowo za pośrednictwem AppContext. setswitch zamiast przy użyciu pliku konfiguracji, jak pokazano w poniższym kodzie:AllowArbitraryDataSetTypeInstantiation can also be set programmatically via AppContext.SetSwitch instead of using a configuration file, as shown in the following code:

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

W przypadku wybrania wcześniejszego podejścia programistycznego wywołanie AppContext.SetSwitch powinno odbywać się wczesne podczas uruchamiania aplikacji.If you choose the preceding programmatic approach, the call to AppContext.SetSwitch should occur early in the apps startup.

Za pomocą rejestru na całym komputerze (.NET Framework 2,0 – 4,8)Through the machine-wide registry (.NET Framework 2.0 - 4.8)

Jeśli AppContext program nie jest dostępny, sprawdzanie ograniczające typy można wyłączyć za pomocą rejestru systemu Windows:If AppContext is not available, type limiting checks can be disabled with the Windows registry:

  • Administrator musi skonfigurować rejestr.An administrator must configure the registry.
  • Korzystanie z rejestru jest zmianą dla całego komputera i wpłynie na wszystkie aplikacje działające na tym komputerze.Using the registry is a machine-wide change and will affect all apps running on the machine.
TypType WartośćValue
Klucz rejestruRegistry key HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext
Nazwa wartościValue name Switch.System.Data.AllowArbitraryDataSetTypeInstantiation
Typ wartościValue type REG_SZ
Dane wartościValue data true

W 64-bitowym systemie operacyjnym, ta wartość musi być dodana zarówno dla klucza 64-bitowego (podanego powyżej), jak i klucza 32-bitowego.On a 64-bit operating system, this value my need to be added for both the 64-bit key (shown above) and the 32-bit key. Klucz 32-bitowy znajduje się w lokalizacji HKLM\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\AppContext .The 32-bit key is located at HKLM\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\AppContext.

Aby uzyskać więcej informacji na temat korzystania z rejestru do konfigurowania AppContext , zobacz "AppContext for Libraryconsumers".For more information on using the registry to configure AppContext, see "AppContext for library consumers".

Bezpieczeństwo w odniesieniu do niezaufanych danych wejściowychSafety with regard to untrusted input

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 niebezpieczne, gdy są wypełniane niezaufanymi danymi wejściowymi.While DataSet and DataTable do impose default limitations on the types that are allowed to be present while deserializing XML payloads, DataSet and DataTable are in general not safe when populated with untrusted input. Poniżej znajduje się niepełna lista sposobów DataSet DataTable odczytywania niezaufanych danych wejściowych lub wystąpienia.The following is a non-exhaustive list of ways that a DataSet or DataTable instance might read untrusted input.

  • Odwołuje się do DataAdapter bazy danych, a DataAdapter.Fill Metoda jest używana do wypełniania DataSet zawartością zapytania bazy danych.A DataAdapter references a database, and the DataAdapter.Fill method is used to populate a DataSet with the contents of a database query.
  • DataSet.ReadXmlMetoda or DataTable.ReadXml służy do odczytywania pliku XML zawierającego informacje o kolumnie i wierszu.The DataSet.ReadXml or DataTable.ReadXml method is used to read an XML file containing column and row information.
  • DataSetWystąpienie lub DataTable jest serializowane jako część usług sieci Web ASP.NET (SOAP) lub punktu końcowego WCF.A DataSet or DataTable instance is serialized as part of a ASP.NET (SOAP) web services or WCF endpoint.
  • Serializator, taki jak XmlSerializer jest używany do deserializacji DataSet DataTable wystąpienia lub ze strumienia XML.A serializer such as XmlSerializer is used to deserialize a DataSet or DataTable instance from an XML stream.
  • Serializator, taki jak JsonConvert jest używany do deserializacji DataSet DataTable wystąpienia lub ze strumienia JSON.A serializer such as JsonConvert is used to deserialize a DataSet or DataTable instance from a JSON stream. JsonConvert to metoda w popularnejNewtonsoft.Jsinnej firmy w bibliotece.JsonConvert is a method in the popular third-party Newtonsoft.Json library.
  • Serializator, taki jak BinaryFormatter jest używany do deserializacji DataSet DataTable wystąpienia lub z strumienia nieprzetworzonych bajtów.A serializer such as BinaryFormatter is used to deserialize a DataSet or DataTable instance from a raw byte stream.

W tym dokumencie omówiono zagadnienia dotyczące bezpieczeństwa w przypadku wcześniejszych scenariuszy.This document discusses safety considerations for the preceding scenarios.

Użyj DataAdapter.Fill , aby wypełnić DataSet z niezaufanego źródła danychUse DataAdapter.Fill to populate a DataSet from an untrusted data source

DataSetWystąpienie może być wypełniane za DataAdapter pomocą DataAdapter.Fill metody, jak pokazano w poniższym przykładzie.A DataSet instance can be populated from a DataAdapter by using the DataAdapter.Fill method, as shown in the following example.

// 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");

(Przykładowy kod jest częścią większego przykładu znalezionego podczas wypełniania zestawu danych z elementu DataAdapter).(The code sample above is part of a larger sample found at Populating a DataSet from a DataAdapter.)

Większość aplikacji może uprościć i założyć, że ich warstwa bazy danych jest zaufana.Most apps can simplify and assume that their database layer is trusted. Niemniej jednak w wykonywaćniu aplikacji do modelowania zagrożeń model zagrożeń może być uważany za granicę zaufania między aplikacją a warstwą bazy danych (serwera).However, if you are in the habit of threat modeling your apps, your threat model may consider there to be a trust boundary between the application (client) and database layer (server). Korzystanie z uwierzytelniania wzajemnego i uwierzytelniania usługi AAD między klientem a serwerem jest jednym ze sposobów, aby pomóc w rozwiązywaniu ryzyka związanego z tym.Using mutual authentication or AAD authentication between client and server is one way to help address the risks associated with this. W pozostałej części tej sekcji omówiono możliwy wynik połączenia klienta z niezaufanym serwerem.The remainder of this section discusses the possible result of a client connecting to an untrusted server.

Konsekwencje wskazywania DataAdapter niezaufanego źródła danych zależą od implementacji DataAdapter samego siebie.The consequences of pointing a DataAdapter at an untrusted data source depend on the implementation of the DataAdapter itself.

Element SqlDataAdapterSqlDataAdapter

W przypadku typu wbudowanego SqlDataAdapterodwołującego się do niezaufanego źródła danych może spowodować atak typu "odmowa usługi" (DOS).For the built-in type SqlDataAdapter, referencing an untrusted data source could result in a denial of service (DoS) attack. Atak na system DoS może spowodować, że aplikacja przestanie odpowiadać lub ulegnie awarii.The DoS attack could result in the app becoming unresponsive or crashing. Jeśli osoba atakująca może zakładać bibliotekę DLL wraz z aplikacją, mogą oni również uzyskać dostęp do lokalnego wykonywania kodu.If an attacker can plant a DLL alongside the app, they may also be able to achieve local code execution.

Inne typy DataAdapterOther DataAdapter types

DataAdapterImplementacje innych firm muszą dokonać własnych ocen, które zapewniają gwarancje bezpieczeństwa, które są przez nie związane z niezaufanymi danymi wejściowymi.Third-party DataAdapter implementations must make their own assessments about what security guarantees they provide in the face of untrusted inputs. Platforma .NET nie może podejmować żadnych gwarancji bezpieczeństwa dotyczących tych implementacji..NET cannot make any safety guarantees regarding these implementations.

DataSet. ReadXml i DataTable. ReadXmlDataSet.ReadXml and DataTable.ReadXml

DataSet.ReadXmlMetody i DataTable.ReadXml nie są bezpieczne, gdy są używane z niezaufanymi danymi wejściowymi.The DataSet.ReadXml and DataTable.ReadXml methods are not safe when used with untrusted input. Zdecydowanie zalecamy, aby zamiast tego rozważyć użycie jednego z alternatyw opisanych w dalszej części tego dokumentu.We strongly recommend that consumers instead consider using one of the alternatives outlined later in this document.

Implementacje DataSet.ReadXml i DataTable.ReadXml zostały pierwotnie utworzone przed lukami w serializacji jako dobrze zrozumieć kategorię zagrożeń.The implementations of DataSet.ReadXml and DataTable.ReadXml were originally created before serialization vulnerabilities were a well-understood threat category. W związku z tym kod nie przestrzega bieżących najlepszych rozwiązań w zakresie zabezpieczeń.As a result, the code does not follow current security best practices. Te interfejsy API mogą służyć jako wektory dla osób atakujących do wykonywania ataków w systemie DoS względem aplikacji sieci Web.These APIs can be used as vectors for attackers to perform DoS attacks against web apps. Ataki te mogą spowodować, że usługa sieci Web nie odpowiada, lub spowodować zakończenie nieoczekiwanego procesu.These attacks might render the web service unresponsive or result in unexpected process termination. Struktura nie zapewnia środków zaradczych dla tych kategorii ataków i .NET traktuje to zachowanie "według projektu".The framework does not provide mitigations for these attack categories and .NET considers this behavior "by design".

Program .NET wydał aktualizacje zabezpieczeń, aby wyeliminować niektóre problemy, takie jak ujawnienie informacji lub zdalne wykonywanie kodu w programie DataSet.ReadXml i DataTable.ReadXml ..NET has released security updates to mitigate some issues such as information disclosure or remote code execution in DataSet.ReadXml and DataTable.ReadXml. Aktualizacje zabezpieczeń platformy .NET mogą nie zapewniać pełnej ochrony przed tymi kategoriami zagrożeń.The .NET security updates may not provide complete protection against these threat categories. Konsumenci powinni ocenić swoje poszczególne scenariusze i rozważyć ich potencjalną ekspozycję na te zagrożenia.Consumers should assess their individual scenarios and consider their potential exposure to these risks.

Klienci powinni mieć świadomość, że aktualizacje zabezpieczeń tych interfejsów API mogą mieć wpływ na zgodność aplikacji w niektórych sytuacjach.Consumers should be aware that security updates to these APIs may impact application compatibility in some situations. Ponadto istnieje możliwość, że nowa Luka w zabezpieczeniach tych interfejsów API zostanie odnaleziona, dla której platforma .NET nie może praktycznie opublikować aktualizacji zabezpieczeń.Furthermore, the possibility exists that a novel vulnerability in these APIs will be discovered for which .NET can't practically publish a security update.

Zalecamy, aby konsumenci tych interfejsów API:We recommend that consumers of these APIs either:

  • Rozważ użycie jednego z alternatyw opisanych w dalszej części tego dokumentu.Consider using one of the alternatives outlined later in this document.
  • Wykonaj indywidualne oceny ryzyka w swoich aplikacjach.Perform individual risk assessments on their apps.

Jedyną odpowiedzialnością dla użytkownika jest określenie, czy mają być używane te interfejsy API.It is the consumer's sole responsibility to determine whether to utilize these APIs. Konsumenci powinni ocenić wszelkie zagrożenia bezpieczeństwa, techniczne i prawne, w tym wymagania prawne, które mogą towarzyszyć za pomocą tych interfejsów API.Consumers should assess any security, technical, and legal risks, including regulatory requirements, that may accompany using these APIs.

DataSet i DataTable za pośrednictwem usług sieci Web ASP.NET lub WCFDataSet and DataTable via ASP.NET web services or WCF

Możliwe jest zaakceptowanie DataSet lub DataTable wystąpienie w usłudze sieci Web ASP.NET (SOAP), jak pokazano w poniższym kodzie:It is possible to accept a DataSet or a DataTable instance in an ASP.NET (SOAP) web service, as demonstrated in the following 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. */
    }
}

Odmiana tego nie jest akceptowana DataSet ani DataTable bezpośrednio jako parametr, ale zamiast tego akceptuje ją w ramach ogólnego grafu serializowanego obiektu SOAP, jak pokazano w poniższym kodzie:A variation on this is not to accept DataSet or DataTable directly as a parameter, but instead to accept it as part of the overall SOAP serialized object graph, as shown in the following 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; }
}

Lub przy użyciu programu WCF zamiast usług sieci Web ASP.NET:Or, using WCF instead of ASP.NET web services:

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 bezpieczeństwa są takie same, jak w sekcji DataSet. ReadXml i DataTable. ReadXml.In all of these cases, the threat model and security guarantees are the same as the DataSet.ReadXml and DataTable.ReadXml section.

Deserializacja zestawu danych lub DataTable za pomocą elementu XmlSerializerDeserialize a DataSet or DataTable via XmlSerializer

Deweloperzy mogą używać XmlSerializer do deserializacji DataSet i DataTable wystąpień, jak pokazano w poniższym kodzie:Developers can use XmlSerializer to deserialize DataSet and DataTable instances, as shown in the following 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; }
}

W takich przypadkach model zagrożeń i gwarancje bezpieczeństwa są takie same, jak w sekcji DataSet. ReadXml i DataTable. ReadXmlIn these cases, the threat model and security guarantees are the same as the DataSet.ReadXml and DataTable.ReadXml section

Deserializacja zestawu danych lub DataTable za pośrednictwem JsonConvertDeserialize a DataSet or DataTable via JsonConvert

Popularnej biblioteki Newtonsoft innej firmy JSON.NET może służyć do deserializacji DataSet i DataTable wystąpień, jak pokazano w poniższym kodzie:The popular third-party Newtonsoft library JSON.NET can be used to deserialize DataSet and DataTable instances, as shown in the following 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; }
}

Deserializacja a DataSet lub DataTable w ten sposób z niezaufanego obiektu BLOB JSON nie jest bezpieczna.Deserializing a DataSet or DataTable in this manner from an untrusted JSON blob is not safe. Ten wzorzec jest narażony na atak typu "odmowa usługi".This pattern is vulnerable to a denial of service attack. Atak może ulec awarii lub nie reagować.Such an attack could crash the app or render it unresponsive.

Uwaga

Firma Microsoft nie gwarantuje ani nie obsługuje implementacji bibliotek innych firm, takich jak Newtonsoft.Json.Microsoft does not warrant or support the implementation of third-party libraries like Newtonsoft.Json. Te informacje są dostarczane w celu zapewnienia kompletności i są dokładne od momentu tego zapisu.This information is provided for completeness and is accurate as of the time of this writing.

Deserializacja zestawu danych lub DataTable za pośrednictwem BinaryFormatterDeserialize a DataSet or DataTable via BinaryFormatter

Deweloperzy nie muszą używać BinaryFormatter , NetDataContractSerializer , SoapFormatter ani pokrewnych niebezpiecznych elementów formatujących do deserializacji DataSet DataTable wystąpienia lub z niezaufanego ładunku:Developers must never use BinaryFormatter, NetDataContractSerializer, SoapFormatter, or related unsafe formatters to deserialize a DataSet or DataTable instance from an untrusted payload:

  • Jest to podatne na pełny atak wykonywania kodu zdalnego.This is susceptible to a full remote code execution attack.
  • Użycie niestandardowych SerializationBinder nie jest wystarczające, aby zapobiec takim atakom.Using a custom SerializationBinder is not sufficient to prevent such an attack.

Bezpieczne zamiennikiSafe replacements

W przypadku aplikacji, które:For apps that either:

  • Akceptuj DataSet lub DataTable za pomocą punktu końcowego protokołu SOAP lub punktu końcowego WCF.Accept DataSet or DataTable through an .asmx SOAP endpoint or a WCF endpoint.
  • Deserializacja niezaufanych danych do wystąpienia DataSet lub DataTable .Deserialize untrusted data into an instance of DataSet or DataTable.

Rozważ zastępowanie modelu obiektów, aby użyć Entity Framework.Consider replacing the object model to use Entity Framework. Entity Framework:Entity Framework:

  • To rozbudowana, nowoczesne, zorientowane obiektowo środowisko, które może reprezentować dane relacyjne.Is a rich, modern, object-oriented framework that can represent relational data.
  • Program udostępnia zróżnicowany ekosystem dostawców baz danych, co ułatwia tworzenie zapytań w bazie danych przy użyciu modeli obiektów Entity Framework.Brings a diverse ecosystem of database providers to make it easy to project database queries via your Entity Framework object models.
  • Oferuje wbudowane zabezpieczenia podczas deserializacji danych z niezaufanych źródeł.Offers built-in protections when deserializing data from untrusted sources.

W przypadku aplikacji korzystających z .aspx punktów końcowych protokołu SOAP Rozważ zmianę tych punktów końcowych na potrzeby korzystania z platformy WCF.For apps that use .aspx SOAP endpoints, consider changing those endpoints to use WCF. WCF to bardziej zaproponowana wymiana .asmx usług sieci Web.WCF is a more fully featured replacement for .asmx web services. Punkty końcowe WCF mogą być udostępniane za pośrednictwem protokołu SOAP w celu zapewnienia zgodności z istniejącymi wywołaniami.WCF endpoints can be exposed via SOAP for compatibility with existing callers.

Analizatory koduCode analyzers

Reguły zabezpieczeń analizatora kodu, które są uruchamiane podczas kompilowania kodu źródłowego, mogą pomóc w znalezieniu luk w zabezpieczeniach związanych z tym problemem z zabezpieczeniami w języku C# i Visual Basic kodzie.Code analyzer security rules, which run when your source code is compiled, can help to find vulnerabilities related to this security issue in C# and Visual Basic code. Microsoft. CodeAnalysis. FxCopAnalyzers to pakiet NuGet analizatorów kodu dystrybuowany na NuGet.org.Microsoft.CodeAnalysis.FxCopAnalyzers is a NuGet package of code analyzers that's distributed on nuget.org.

Aby zapoznać się z omówieniem analizatorów kodu, zobacz Omówienie analizatorów kodu źródłowego.For an overview of code analyzers, see Overview of source code analyzers.

Włącz następujące reguły Microsoft. CodeAnalysis. FxCopAnalyzers:Enable the following Microsoft.CodeAnalysis.FxCopAnalyzers rules:

  • CA2350: nie należy używać elementu DataTable. ReadXml () z niezaufanymi danymiCA2350: Do not use DataTable.ReadXml() with untrusted data
  • CA2351: nie należy używać zestawu danych. ReadXml () z niezaufanymi danymiCA2351: Do not use DataSet.ReadXml() with untrusted data
  • CA2352: niebezpieczny zestaw danych lub DataTable w typie możliwym do serializacji może być narażony na ataki zdalnego wykonywania koduCA2352: Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks
  • CA2353: niebezpieczny zestaw danych lub DataTable w typie możliwym do serializacjiCA2353: Unsafe DataSet or DataTable in serializable type
  • CA2354: niebezpieczny zestaw danych lub DataTable w odszeregowanym grafie obiektów może być narażony na ataki zdalnego wykonywania koduCA2354: Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks
  • CA2355: znaleziono niebezpieczny typ elementu dataset lub typu DataTable w grafie obiektu, który można zdeserializowaćCA2355: Unsafe DataSet or DataTable type found in deserializable object graph
  • CA2356: niebezpieczny typ zestawu danych lub typu DataTable w grafie obiektów do serializacji sieci WebCA2356: Unsafe DataSet or DataTable type in web deserializable object graph
  • CA2361: Upewnij się, że automatycznie wygenerowana Klasa zawierająca zestaw danych. ReadXml () nie jest używana z niezaufanymi danymiCA2361: Ensure autogenerated class containing DataSet.ReadXml() is not used with untrusted data
  • CA2362: niebezpieczny zestaw danych lub DataTable w automatycznie generowanym typie możliwym do serializacji może być narażony na ataki zdalnego wykonywania koduCA2362: Unsafe DataSet or DataTable in autogenerated serializable type can be vulnerable to remote code execution attacks

Aby uzyskać więcej informacji na temat konfigurowania reguł, zobacz Korzystanie z analizatorów kodu.For more information about configuring rules, see Use code analyzers.

Nowe reguły zabezpieczeń są dostępne w następujących pakietach NuGet:The new security rules are available in the following NuGet packages:

  • Microsoft. CodeAnalysis. FxCopAnalyzers 3.3.0: for Visual Studio 2019 w wersji 16,3 lub nowszejMicrosoft.CodeAnalysis.FxCopAnalyzers 3.3.0: for Visual Studio 2019 version 16.3 or later
  • Microsoft. CodeAnalysis. FxCopAnalyzers 2.9.11: for Visual Studio 2017 w wersji 15,9 lub nowszejMicrosoft.CodeAnalysis.FxCopAnalyzers 2.9.11: for Visual Studio 2017 version 15.9 or later