Bagikan melalui


Panduan keamanan DataSet dan DataTable

Artikel ini berlaku untuk:

  • .NET Framework (semua versi)
  • .NET Core dan yang lebih baru
  • .NET 5 dan yang lebih baru

Jenis DataSet dan DataTable adalah komponen .NET lama yang memungkinkan mewakili himpunan data sebagai objek terkelola. Komponen-komponen ini diperkenalkan di .NET Framework 1.0 sebagai bagian dari infrastruktur ADO.NET asli. Tujuan mereka adalah untuk memberikan tampilan terkelola atas kumpulan data relasional, mengabstraksikan apakah sumber data yang mendasarinya adalah XML, SQL, atau teknologi lain.

Untuk informasi selengkapnya tentang ADO.NET, termasuk paradigma tampilan data yang lebih modern, lihat dokumentasi ADO.NET.

Pembatasan default saat mendeserialisasi DatasSet atau DataTable dari XML

Pada semua versi .NET Framework, .NET Core, dan .NET yang didukung, DataSet dan DataTable menempatkan batasan berikut pada jenis objek apa yang mungkin ada dalam data yang dideserialisasi. Secara default, daftar ini dibatasi untuk:

  • Primitif dan setara primitif: 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, dan SqlString.
  • Non-primitif yang umum digunakan: Type, Uri, dan BigInteger.
  • Jenis System.Drawing yang umum digunakan: Color, Point, PointF, Rectangle, RectangleF, Size, dan SizeF.
  • Enum jenis.
  • Array dan daftar jenis di atas.

Jika data XML masuk berisi objek yang tipenya tidak ada dalam daftar ini:

  • Pengecualian dilemparkan dengan pesan berikut dan jejak tumpukan. Pesan Kesalahan: System.InvalidOperationException : Type '<Type Name>, Version=<n.n.n.n>, Culture=<culture>, PublicKeyToken=<token value>' tidak diizinkan di sini. Stack Trace: di System.Data.TypeLimiter.EnsureTypeIsAllowed(Type type, TypeLimiter capturedLimiter) di System.Data.DataColumn.UpdateColumnType(Type type, StorageType typeCode) di System.Data.DataColumn.set_DataType(Type value)

  • Operasi deserialisasi gagal.

Saat memuat XML ke dalam instans DataSet atau DataTable yang sudah ada, definisi kolom yang ada juga dipertimbangkan. Jika tabel sudah berisi definisi kolom dari jenis kustom, jenis tersebut untuk sementara ditambahkan ke daftar izinkan selama durasi operasi deserialisasi XML.

Catatan

Setelah Anda menambahkan kolom ke DataTable, ReadXml tidak akan membaca skema dari XML, dan jika skema tidak cocok, kolom juga tidak akan dibaca dalam rekaman, jadi Anda harus menambahkan semua kolom sendiri untuk menggunakan metode ini.

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

Pembatasan jenis objek juga berlaku saat menggunakan XmlSerializer untuk mendeserialisasi instans DataSet atau DataTable. Namun, mereka mungkin tidak berlaku saat menggunakan BinaryFormatter untuk mendeserialisasi instans DataSet atau DataTable.

Pembatasan jenis objek tidak berlaku saat menggunakan DataAdapter.Fill, seperti ketika instans DataTable diisi langsung dari database tanpa menggunakan API deserialisasi XML.

Memperluas daftar jenis yang diizinkan

Aplikasi dapat memperluas daftar jenis yang diizinkan untuk menyertakan jenis kustom selain jenis bawaan yang tercantum di atas. Jika memperluas daftar jenis yang diizinkan, perubahan akan memengaruhi semua DataSet instans dan DataTable dalam aplikasi. Tipe tidak dapat dihapus dari daftar tipe bawaan yang diizinkan.

Memperluas melalui konfigurasi (.NET Framework 4.0 dan yang lebih baru)

App.config dapat digunakan untuk memperluas daftar tipe yang diizinkan. Untuk memperluas daftar tipe yang diizinkan:

  • Gunakan elemen <configSections> untuk menambahkan referensi ke bagian konfigurasi System.Data.
  • Gunakan <system.data.dataset.serialization>/<allowedTypes> untuk menentukan jenis tambahan.

Setiap elemen <add> hanya boleh menentukan satu jenis dengan menggunakan nama jenis rakitan yang memenuhi syarat. Untuk menambahkan jenis tambahan ke daftar jenis yang diizinkan, gunakan beberapa elemen <add>.

Contoh berikut menunjukkan perluasan daftar jenis yang diizinkan dengan menambahkan jenis kustom 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>

Untuk mengambil nama tipe yang memenuhi syarat assembly, gunakan properti Type.AssemblyQualifiedName, seperti yang ditunjukkan dalam kode berikut.

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

Memperluas melalui konfigurasi (.NET Framework 2.0 - 3.5)

Jika aplikasi Anda menargetkan .NET Framework 2.0 atau 3.5, Anda masih dapat menggunakan mekanisme App.config di atas untuk memperluas daftar jenis yang diizinkan. Namun, elemen <configSections> Anda akan terlihat sedikit berbeda, seperti yang ditunjukkan dalam kode berikut:

<?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>

Perluas secara terprogram (.NET Framework, .NET Core, .NET 5+)

Daftar jenis yang diizinkan juga dapat diperluas secara terprogram dengan menggunakan AppDomain.SetData dengan kunci terkenal System.Data.DataSetDefaultAllowedTypes, seperti yang ditunjukkan dalam kode berikut.

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

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

Jika menggunakan mekanisme ekstensi, nilai yang terkait dengan kunci System.Data.DataSetDefaultAllowedTypes harus berjenis Type[].

Pada .NET Framework, daftar jenis yang diizinkan dapat diperluas baik dengan App.config dan AppDomain.SetData. Dalam hal ini, DataSet dan DataTable akan memungkinkan objek untuk dideserialisasi sebagai bagian dari data jika jenisnya ada di salah satu daftar.

Menjalankan aplikasi dalam mode audit (.NET Framework)

Dalam .NET Framework, DataSet dan DataTable menyediakan kemampuan mode audit. Saat mode audit diaktifkan, DataSet dan DataTable membandingkan jenis objek masuk dengan daftar jenis yang diizinkan. Namun, jika objek yang jenisnya tidak diizinkan terlihat, pengecualian tidak dilemparkan. Sebagai gantinya, DataSet dan DataTable memberi tahu setiap instans TraceListener terlampir bahwa jenis yang mencurigakan ada, memungkinkan TraceListener untuk mencatat informasi ini. Tidak ada pengecualian yang dilemparkan dan operasi deserialisasi berlanjut.

Peringatan

Menjalankan aplikasi dalam "mode audit" hanya boleh menjadi langkah sementara yang digunakan untuk pengujian. Saat mode audit diaktifkan, DataSet dan DataTable jangan memberlakukan pembatasan jenis, yang dapat memperkenalkan lubang keamanan di dalam aplikasi Anda. Untuk informasi selengkapnya, lihat bagian berjudul Menghapus semua batasan jenis dan Keamanan sehubungan dengan input yang tidak tepercaya.

Mode audit dapat diaktifkan melalui App.config:

  • Lihat bagian Memperluas melalui konfigurasi dalam dokumen ini untuk informasi tentang nilai yang tepat untuk dimasukkan ke elemen <configSections>.
  • Gunakan <allowedTypes auditOnly="true"> untuk mengaktifkan mode audit, seperti yang ditunjukkan pada markup berikut.
<?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>

Setelah mode audit diaktifkan, Anda dapat menggunakan App.config untuk menghubungkan pilihan TraceListener Anda ke DataSet bawaan TraceSource. Nama sumber jejak bawaan adalah Sistem .Data.DataSet. Contoh berikut menunjukkan penulisan peristiwa pelacakan ke konsol dan ke file log di 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>

Untuk informasi selengkapnya tentang TraceSource dan TraceListener, lihat dokumen Cara: Menggunakan TraceSource dan Filter dengan Pendengar Jejak.

Catatan

Menjalankan aplikasi dalam mode audit tidak tersedia di .NET Core atau di .NET 5 dan yang lebih baru.

Menghapus semua batasan jenis

Jika aplikasi harus menghapus semua batasan pembatasan jenis dari DataSet dan DataTable:

  • Ada beberapa opsi untuk menekan pembatasan limit jenis.
  • Opsi yang tersedia bergantung pada kerangka kerja target aplikasi.

Peringatan

Menghapus semua batasan jenis dapat memperkenalkan lubang keamanan di dalam aplikasi. Saat menggunakan mekanisme ini, pastikan aplikasi tidak menggunakan DataSet atau DataTable untuk membaca input yang tidak tepercaya. Untuk informasi selengkapnya, lihat CVE-2020-1147 dan bagian berikut berjudul Keamanan sehubungan dengan input yang tidak tepercaya.

Melalui konfigurasi AppContext (.NET Framework 4.6 dan yang lebih baru, .NET Core 2.1 dan yang lebih baru, .NET 5 dan yang lebih baru)

Sakelar AppContext, Switch.System.Data.AllowArbitraryDataSetTypeInstantiation, ketika diatur ke true menghapus semua batasan pembatasan jenis dari DataSet dan DataTable.

Dalam .NET Framework, sakelar ini dapat diaktifkan melalui App.config, seperti yang ditunjukkan dalam konfigurasi berikut:

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

Dalam ASP.NET, elemen <AppContextSwitchOverrides> tidak tersedia. Sebagai gantinya, sakelar dapat diaktifkan melalui Web.config, seperti yang ditunjukkan dalam konfigurasi berikut:

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

Untuk informasi selengkapnya, lihat elemen <AppContextSwitchOverrides>.

Di .NET Core, .NET 5, dan ASP.NET Core, pengaturan ini dikontrol oleh runtimeconfig.json, seperti yang ditunjukkan dalam JSON berikut:

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

Untuk informasi selengkapnya, lihat ".NET Core runtime configuration settings".

AllowArbitraryDataSetTypeInstantiation juga dapat diatur secara terprogram melalui AppContext.SetSwitch alih-alih menggunakan file konfigurasi, seperti yang ditunjukkan dalam kode berikut:

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

Jika Anda memilih pendekatan terprogram sebelumnya, panggilan ke AppContext.SetSwitch akan terjadi di awal startup aplikasi.

Melalui registri di seluruh komputer (.NET Framework 2.0 - 4.x)

Jika AppContext tidak tersedia, pemeriksaan pembatasan jenis dapat dinonaktifkan dengan registri Windows:

  • Administrator harus mengonfigurasi registri.
  • Menggunakan registri adalah perubahan di seluruh komputer dan akan memengaruhi semua aplikasi yang berjalan di komputer.
Tipe Nilai
Kunci Registri HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext
Nama nilai Switch.System.Data.AllowArbitraryDataSetTypeInstantiation
Jenis nilai REG_SZ
Data Nilai true

Pada sistem operasi 64-bit, nilai ini yang perlu saya tambahkan untuk kunci 64-bit (ditunjukkan di atas) dan kunci 32-bit. Kunci 32-bit terletak di HKLM\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\AppContext.

Untuk informasi selengkapnya tentang menggunakan registri untuk mengonfigurasi AppContext, lihat "AppContext untuk konsumen pustaka".

Keamanan sehubungan dengan input yang tidak tepercaya

Sementara DataSet dan DataTable memberlakukan batasan default pada jenis yang diizinkan untuk hadir saat mendeserialisasi payload XML, DataSet dan DataTable secara umum tidak aman ketika diisi dengan input yang tidak tepercaya. Berikut ini adalah daftar cara yang tidak lengkap bahwa instans DataSet atau DataTable mungkin membaca input yang tidak tepercaya.

  • Referensi DataAdapter database, dan metode DataAdapter.Fill digunakan untuk mengisi DataSet dengan konten kueri database.
  • Metode DataSet.ReadXml atau DataTable.ReadXml digunakan untuk membaca file XML yang berisi informasi kolom dan baris.
  • Instans DataSet atau DataTable diserialisasikan sebagai bagian dari layanan web ASP.NET (SOAP) atau titik akhir WCF.
  • Pembuat serialisasi seperti XmlSerializer digunakan untuk mendeserialisasi instans DataSet atau DataTable dari aliran XML.
  • Pembuat serialisasi seperti JsonConvert digunakan untuk mendeserialisasi instans DataSet atau DataTable dari aliran JSON. JsonConvert adalah metode di pustaka Newtonsoft.Json pihak ketiga yang populer.
  • Pembuat serialisasi seperti BinaryFormatter digunakan untuk mendeserialisasi instans DataSet atau DataTable dari aliran byte mentah.

Dokumen ini membahas pertimbangan keamanan untuk skenario sebelumnya.

Gunakan DataAdapter.Fill untuk mengisi DataSet dari sumber data yang tidak tepercaya

Instans DataSet dapat diisi dari DataAdapter dengan menggunakan metode DataAdapter.Fill, seperti yang ditunjukkan pada contoh berikut.

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

(Sampel kode di atas adalah bagian dari sampel yang lebih besar yang ditemukan di Mengisi Himpunan Data dari DataAdapter.)

Sebagian besar aplikasi dapat menyederhanakan dan mengasumsikan bahwa lapisan database mereka tepercaya. Namun, jika Anda terbiasa memodelkan ancaman aplikasi Anda, model ancaman Anda mungkin menganggap ada batas kepercayaan antara aplikasi (klien) dan lapisan database (server). Menggunakan autentikasi timbal balik atau autentikasi AAD antara klien dan server adalah salah satu cara untuk membantu mengatasi risiko yang terkait dengan ini. Sisa bagian ini membahas kemungkinan hasil klien yang terhubung ke server yang tidak tepercaya.

Konsekuensi dari menunjuk DataAdapter ke sumber data yang tidak tepercaya tergantung pada implementasi DataAdapter nya sendiri.

SqlDataAdapter

Untuk SqlDataAdapter jenis bawaan, mereferensikan sumber data yang tidak tepercaya dapat mengakibatkan serangan penolakan layanan (DoS). Serangan DoS dapat mengakibatkan aplikasi menjadi tidak responsif atau crash. Jika penyerang dapat menanam DLL bersama aplikasi, mereka mungkin juga dapat mencapai eksekusi kode lokal.

Jenis DataAdapter lainnya

Implementasi DataAdapter pihak ketiga harus membuat penilaian sendiri tentang jaminan keamanan apa yang mereka berikan dalam menghadapi input yang tidak tepercaya. .NET tidak dapat membuat jaminan keamanan apa pun mengenai implementasi ini.

DataSet.ReadXml dan DataTable.ReadXml

Metode DataSet.ReadXml dan DataTable.ReadXml tidak aman ketika digunakan dengan input yang tidak tepercaya. Kami sangat menyarankan agar konsumen mempertimbangkan untuk menggunakan salah satu alternatif yang diuraikan nanti dalam dokumen ini.

Implementasi DataSet.ReadXml dan DataTable.ReadXml awalnya dibuat sebelum kerentanan serialisasi adalah kategori ancaman yang dipahami dengan baik. Akibatnya, kode tidak mengikuti praktik terbaik keamanan saat ini. API ini dapat digunakan sebagai vektor bagi penyerang untuk melakukan serangan DoS terhadap aplikasi web. Serangan ini mungkin membuat layanan web tidak responsif atau mengakibatkan penghentian proses yang tidak terduga. Kerangka kerja tidak memberikan mitigasi untuk kategori serangan ini dan .NET mempertimbangkan perilaku ini "berdasarkan desain".

.NET telah merilis pembaruan keamanan untuk mengurangi beberapa masalah seperti pengungkapan informasi atau eksekusi kode jarak jauh di DataSet.ReadXml dan DataTable.ReadXml. Pembaruan keamanan .NET mungkin tidak memberikan perlindungan penuh terhadap kategori ancaman ini. Konsumen harus menilai skenario individu mereka dan mempertimbangkan potensi paparan mereka terhadap risiko ini.

Konsumen harus menyadari bahwa pembaruan keamanan untuk API ini dapat memengaruhi kompatibilitas aplikasi dalam beberapa situasi. Selain itu, kemungkinan ada bahwa kerentanan baru dalam API ini akan ditemukan di mana .NET tidak dapat secara praktis menerbitkan pembaruan keamanan.

Kami menyarankan agar konsumen API ini:

  • Mempertimbangkan untuk menggunakan salah satu alternatif yang diuraikan nanti dalam dokumen ini.
  • Melakukan penilaian risiko individu pada aplikasi mereka.

Konsumen bertanggung jawab sepenuhnya untuk menentukan apakah akan menggunakan API ini. Konsumen harus menilai risiko keamanan, teknis, dan hukum apa pun, termasuk persyaratan peraturan, yang dapat menyertai penggunaan API ini.

DataSet dan DataTable melalui layanan web ASP.NET atau WCF

Dimungkinkan untuk menerima instans DataSet atau DataTable dalam layanan web ASP.NET (SOAP), seperti yang ditunjukkan dalam kode berikut:

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. */
    }
}

Variasi tentang ini bukan untuk menerima DataSet atau DataTable langsung sebagai parameter, tetapi sebaliknya untuk menerimanya sebagai bagian dari grafik objek berseri SOAP secara keseluruhan, seperti yang ditunjukkan dalam kode berikut:

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; }
}

Atau, menggunakan WCF alih-alih ASP.NET layanan web:

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; }
}

Dalam semua kasus ini, model ancaman dan jaminan keamanan sama dengan bagian DataSet.ReadXml dan DataTable.ReadXml.

Mendeserialisasi Himpunan Data atau DataTable melalui XmlSerializer

Pengembang dapat menggunakan XmlSerializer untuk mendeserialisasi instans DataSet dan DataTable, seperti yang ditunjukkan dalam kode berikut:

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; }
}

Dalam kasus ini, model ancaman dan jaminan keamanan sama dengan bagian DataSet.ReadXml dan DataTable.ReadXml

Mendeserialisasi Himpunan Data atau DataTable melalui JsonConvert

Pustaka Newtonsoft pihak ketiga populer Json.NET dapat digunakan untuk deserialisasi instans DataSet dan DataTable, seperti yang ditunjukkan dalam kode berikut:

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; }
}

Mendeserialisasi DataSet atau DataTable dengan cara ini dari blob JSON yang tidak tepercaya tidak aman. Pola ini rentan terhadap penolakan serangan layanan. Serangan semacam itu dapat merusak aplikasi atau membuatnya tidak responsif.

Catatan

Microsoft tidak menjamin atau mendukung implementasi pustaka pihak ketiga seperti Newtonsoft.Json. Informasi ini diberikan untuk kelengkapan dan akurat pada saat penulisan ini.

Deserialisasi DataSet atau DataTable melalui BinaryFormatter

Anda tidak boleh menggunakan BinaryFormatterNetDataContractSerializer, , SoapFormatter, atau pemformat tidak aman terkait untuk mendeserialisasi DataSet instans atau DataTable dari payload yang tidak tepercaya:

  • Ini rentan terhadap serangan eksekusi kode jarak jauh penuh.
  • Menggunakan kustom SerializationBinder tidak cukup untuk mencegah serangan tersebut.

Penggantian aman

Untuk aplikasi yang:

  • Menerima DataSet atau DataTable melalui titik akhir SOAP .asmx atau titik akhir WCF.
  • Mendeserialisasi data yang tidak tepercaya ke dalam instans DataSet atau DataTable.

Pertimbangkan untuk mengganti model objek untuk menggunakan Entity Framework. Entity Framework:

  • Adalah kerangka kerja yang kaya, modern, berorientasi objek yang dapat mewakili data relasional.
  • Menghadirkan beragam ekosistem penyedia database untuk memudahkan proyeksi kueri database melalui model objek Entity Framework Anda.
  • Menawarkan perlindungan bawaan saat mendeserialisasi data dari sumber yang tidak tepercaya.

Untuk aplikasi yang menggunakan .aspx titik akhir SOAP, pertimbangkan untuk mengubah titik akhir tersebut untuk menggunakan WCF. WCF adalah pengganti yang lebih berkinerja penuh untuk layanan web .asmx. Titik akhir WCF dapat diekspos melalui SOAP untuk kompatibilitas dengan pemanggil yang sudah ada.

Penganalisis kode

Aturan keamanan penganalisis kode, yang berjalan saat kode sumber Anda dikompilasi, dapat membantu menemukan kerentanan yang terkait dengan masalah keamanan ini dalam kode C# dan Visual Basic. Microsoft.CodeAnalysis.FxCopAnalyzers adalah paket NuGet penganalisis kode yang didistribusikan pada nuget.org.

Untuk gambaran umum penganalisis kode, lihat Gambaran umum penganalisis kode sumber.

Aktifkan aturan Microsoft.CodeAnalysis.FxCopAnalyzers berikut:

Untuk informasi selengkapnya tentang mengonfigurasi aturan, lihat Menggunakan penganalisis kode.

Aturan keamanan baru tersedia dalam paket NuGet berikut:

  • Microsoft.CodeAnalysis.FxCopAnalyzers 3.3.0: untuk Visual Studio 2019 versi 16.3 atau yang lebih baru
  • Microsoft.CodeAnalysis.FxCopAnalyzers 2.9.11: untuk Visual Studio 2017 versi 15.9 atau yang lebih baru