Baca dalam bahasa Inggris

Bagikan melalui


CA2327: Jangan gunakan JsonSerializerSettings yang tidak aman

Properti Nilai
ID Aturan CA2327
Judul Jangan gunakan JsonSerializerSettings yang tidak aman
Golongan Keamanan
Perbaikan bersifat disruptif atau non-disruptif Non-disruptif
Diaktifkan secara default di .NET 9 No

Penyebab

Aturan ini diaktifkan ketika kedua kondisi berikut terpenuhi untuk instans Newtonsoft.Json.JsonSerializerSettings:

Instans JsonSerializerSettings harus digunakan dengan salah satu cara berikut:

Secara default, aturan ini menganalisis seluruh codebase, tetapi ini dapat dikonfigurasi.

Deskripsi aturan

Pendeserialisasi yang tidak aman rentan saat mendeserialisasi data yang tidak tepercaya. Penyerang dapat mengubah data yang diserialisasikan untuk memasukkan jenis tidak terduga untuk menyuntikkan objek dengan efek samping yang berbahaya. Serangan terhadap pendeserialisasi yang tidak aman dapat, misalnya, menjalankan perintah pada sistem operasi dasar, berkomunikasi melalui jaringan, atau menghapus file.

Aturan ini menemukan instans Newtonsoft.Json.JsonSerializerSettings yang dikonfigurasi untuk mendeserialisasi jenis yang ditentukan dari input, tetapi tidak dikonfigurasi untuk membatasi jenis yang dideserialisasi dengan Newtonsoft.Json.Serialization.ISerializationBinder. Jika Anda ingin melarang deserialisasi jenis yang ditentukan dari input sepenuhnya, nonaktifkan aturan CA2327, CA2328, CA2329, dan CA2330, lalu aktifkan aturan CA2326 sebagai gantinya.

Cara memperbaiki pelanggaran

Kapan harus menekan peringatan

Aman untuk menyembunyikan peringatan dari aturan ini jika:

  • Anda mengetahui bahwa input-nya tepercaya. Pertimbangkan bahwa batas kepercayaan dan aliran data aplikasi Anda dapat berubah dari waktu ke waktu.
  • Anda telah mengambil salah satu tindakan pencegahan dalam Cara memperbaiki pelanggaran.

Menyembunyikan peringatan

Jika Anda hanya ingin menyembunyikan satu pelanggaran, tambahkan arahan praprosedur ke file sumber Anda untuk dinonaktifkan lalu aktifkan kembali aturannya.

C#
#pragma warning disable CA2327
// The code that's violating the rule is on this line.
#pragma warning restore CA2327

Untuk menonaktifkan aturan untuk file, folder, atau proyek, atur tingkat keparahannya ke none dalam file konfigurasi.

ini
[*.{cs,vb}]
dotnet_diagnostic.CA2327.severity = none

Untuk informasi selengkapnya, lihat Cara menyembunyikan peringatan analisis kode.

Mengonfigurasi kode yang akan dianalisis

Gunakan opsi berikut untuk mengonfigurasi bagian mana dari codebase Anda yang akan menjalankan aturan ini.

Anda dapat mengonfigurasi opsi ini hanya untuk aturan ini, untuk semua aturan yang berlaku, atau untuk semua aturan dalam kategori ini (Security) yang berlaku untuk aturan tersebut. Untuk informasi selengkapnya, lihat Opsi konfigurasi aturan kualitas kode.

Mengecualikan simbol tertentu

Anda dapat mengecualikan simbol tertentu, seperti jenis dan metode, dari analisis dengan mengatur opsi excluded_symbol_names. Misalnya, untuk menentukan bahwa aturan tidak boleh berjalan pada kode apa pun dalam jenis bernama MyType, tambahkan pasangan kunci-nilai berikut ke file .editorconfig di proyek Anda:

ini
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

Catatan

Ganti bagian XXXXCAXXXX dengan ID aturan yang berlaku.

Format nama simbol yang diizinkan pada nilai opsi (dipisahkan oleh |):

  • Nama simbol saja (menyertakan semua simbol dengan nama, terlepas dari jenis atau namespace yang memuatnya).
  • Nama yang sepenuhnya memenuhi syarat dalam format ID dokumentasi simbol. Setiap nama simbol memerlukan awalan jenis simbol, seperti M: untuk metode, T: untuk jenis, dan N: untuk namespace.
  • .ctor untuk konstruktor dan .cctor untuk konstruktor statik.

Contoh:

Nilai Opsi Ringkasan
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType Mencocokkan semua simbol bernama MyType.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 Mencocokkan semua simbol bernama MyType1 atau MyType2.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) Mencocokkan MyMethod metode tertentu dengan tanda tangan yang sepenuhnya memenuhi syarat yang ditentukan.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) Mencocokkan MyMethod1 dan MyMethod2 metode tertentu dengan masing-masing tanda tangan yang sepenuhnya memenuhi syarat.

Mengecualikan jenis tertentu dan jenis turunannya

Anda dapat mengecualikan jenis tertentu dan jenis turunannya dari analisis dengan mengatur opsi excluded_type_names_with_derived_types. Misalnya, untuk menentukan bahwa aturan tidak boleh dijalankan pada metode apa pun dalam jenis bernama MyType dan jenis turunannya, tambahkan pasangan kunci-nilai berikut ke file .editorconfig di proyek Anda:

ini
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

Catatan

Ganti bagian XXXXCAXXXX dengan ID aturan yang berlaku.

Format nama simbol yang diizinkan pada nilai opsi (dipisahkan oleh |):

  • Nama jenis saja (mencakup semua jenis dengan nama, terlepas dari jenis atau namespace yang memuatnya).
  • Nama yang sepenuhnya memenuhi syarat dalam format ID dokumentasi simbol, dengan awalan T: opsional.

Contoh:

Nilai opsi Ringkasan
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType Mencocokkan semua jenis bernama MyType dan semua jenis turunannya.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 Mencocokkan semua jenis bernama MyType1 atau MyType2 dan semua jenis turunannya.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType Mencocokkan MyType jenis tertentu dengan nama yang sepenuhnya memenuhi syarat tertentu dan semua jenis turunannya.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 Mencocokkan MyType1 dan MyType2 jenis tertentu dengan masing-masing nama yang sepenuhnya memenuhi syarat, dan semua jenis turunannya.

Contoh kode semu

Pelanggaran

C#
using Newtonsoft.Json;

public class BookRecord
{
    public string Title { get; set; }
    public object Location { get; set; }
}

public abstract class Location
{
    public string StoreId { get; set; }
}

public class AisleLocation : Location
{
    public char Aisle { get; set; }
    public byte Shelf { get; set; }
}

public class WarehouseLocation : Location
{
    public string Bay { get; set; }
    public byte Shelf { get; set; }
}

public class ExampleClass
{
    public BookRecord DeserializeBookRecord(string s)
    {
        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.TypeNameHandling = TypeNameHandling.Auto;
        return JsonConvert.DeserializeObject<BookRecord>(s, settings);    // CA2327 violation
    }
}

Solusi

C#
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

public class BookRecordSerializationBinder : ISerializationBinder
{
    // To maintain backwards compatibility with serialized data before using an ISerializationBinder.
    private static readonly DefaultSerializationBinder Binder = new DefaultSerializationBinder();

    public void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        Binder.BindToName(serializedType, out assemblyName, out typeName);
    }

    public Type BindToType(string assemblyName, string typeName)
    {
        // If the type isn't expected, then stop deserialization.
        if (typeName != "BookRecord" && typeName != "AisleLocation" && typeName != "WarehouseLocation")
        {
            return null;
        }

        return Binder.BindToType(assemblyName, typeName);
    }
}

public class BookRecord
{
    public string Title { get; set; }
    public object Location { get; set; }
}

public abstract class Location
{
    public string StoreId { get; set; }
}

public class AisleLocation : Location
{
    public char Aisle { get; set; }
    public byte Shelf { get; set; }
}

public class WarehouseLocation : Location
{
    public string Bay { get; set; }
    public byte Shelf { get; set; }
}

public class ExampleClass
{
    public BookRecord DeserializeBookRecord(string s)
    {
        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.TypeNameHandling = TypeNameHandling.Auto;
        settings.SerializationBinder = new BookRecordSerializationBinder();
        return JsonConvert.DeserializeObject<BookRecord>(s, settings);
    }
}

CA2326: Jangan gunakan nilai TypeNameHandling selain None

CA2328: Pastikan JsonSerializerSettings aman

CA2329: Jangan mendeserialisasi dengan JsonSerializer menggunakan konfigurasi yang tidak aman

CA2330: Pastikan JsonSerializer memiliki konfigurasi yang aman saat mendeserialisasi