CA2105: Dizi alanları salt okunur olmamalıdır

Ürün Değer
RuleId CA2105
Kategori Microsoft.Security
Hataya neden olan değişiklik Yeni

Neden

Bir diziyi barındıran genel veya korumalı alan salt okunur olarak bildirilir.

Dekont

Bu kural kullanım dışı bırakıldı. Daha fazla bilgi için bkz . Kullanım dışı kurallar.

Kural açıklaması

(ReadOnly Visual Basic'te) değiştiricisini readonly dizi içeren bir alana uyguladığınızda, alan farklı bir diziye başvuracak şekilde değiştirilemez. Bir dizinin öğeleri salt okunur bir alanda depolanmış olsa bile değiştirilebilir. Genel olarak erişilebilen salt okunur bir dizinin öğelerini temel alan kararlar alan veya işlemler gerçekleştiren kod, güvenlik açığından yararlanılabilir bir güvenlik açığı içerebilir.

Ortak bir alana sahip olmanın ca1051 tasarım kuralını da ihlal ettiğini unutmayın: Görünür örnek alanları bildirmeyin.

İhlalleri düzeltme

Bu kural tarafından tanımlanan güvenlik açığını düzeltmek için, genel olarak erişilebilen salt okunur bir dizinin içeriğine güvenmeyin. Aşağıdaki yordamlardan birini kullanmanız kesinlikle önerilir:

  • dizisini değiştirilemeyen kesin olarak belirlenmiş bir koleksiyonla değiştirin. Daha fazla bilgi için bkz. System.Collections.ReadOnlyCollectionBase.

  • Ortak alanı, özel dizinin bir kopyasını döndüren bir yöntemle değiştirin. Kodunuz kopyaya güvenmediğinden, öğeler değiştirilirse herhangi bir tehlike yoktur.

İkinci yaklaşımı seçtiyseniz, alanı bir özellik ile değiştirmeyin; dizileri döndüren özellikler performansı olumsuz etkiler. Daha fazla bilgi için bkz . CA1819: Özellikler dizi döndürmemelidir.

Uyarıların ne zaman bastırılması gerekiyor?

Bu kuraldan bir uyarının dışlanması kesinlikle önerilmez. Salt okunur bir alanın içeriğinin önemli olmadığı neredeyse hiç senaryo gerçekleşmez. Senaryonuzda böyle bir durum söz konusuysa, iletiyi dışlamak yerine değiştiriciyi kaldırın readonly .

Örnek 1

Bu örnek, bu kuralı ihlal etme tehlikelerini gösterir. İlk bölümde, MyClassWithReadOnlyArrayFieldgüvenli olmayan iki alan (grades ve privateGrades) içeren türüne sahip bir örnek kitaplık gösterilmektedir. Alan grades geneldir ve bu nedenle çağıranlara karşı savunmasızdır. Alan privateGrades özeldir, ancak yine de yöntemi tarafından GetPrivateGrades çağıranlara döndürülür. Alan securePrivateGrades , yöntemi tarafından güvenli bir şekilde kullanıma sunulur GetSecurePrivateGrades . İyi tasarım uygulamalarını izlemek için özel olarak bildirilir. İkinci bölümde ve privateGrades üyelerinde grades depolanan değerleri değiştiren kod gösterilir.

Örnek sınıf kitaplığı aşağıdaki örnekte görüntülenir.

using System;

namespace SecurityRulesLibrary
{
   public class MyClassWithReadOnlyArrayField
   {
      public readonly int[] grades = {90, 90, 90};
      private readonly int[] privateGrades = {90, 90, 90};
      private readonly int[] securePrivateGrades = {90, 90, 90};

      // Making the array private does not protect it because it is passed to others.
      public int[] GetPrivateGrades()
      {
         return privateGrades;
      }
      //This method secures the array by cloning it.
      public int[] GetSecurePrivateGrades()
      {
            return (int[])securePrivateGrades.Clone();
      }

      public override string ToString() 
      {
         return String.Format("Grades: {0}, {1}, {2} Private Grades: {3}, {4}, {5}  Secure Grades, {6}, {7}, {8}", 
            grades[0], grades[1], grades[2], privateGrades[0], privateGrades[1], privateGrades[2], securePrivateGrades[0], securePrivateGrades[1], securePrivateGrades[2]);
      }     
   }
}

Örnek 2

Aşağıdaki kod, salt okunur dizi güvenlik sorunlarını göstermek için örnek sınıf kitaplığını kullanır.

using System;
using SecurityRulesLibrary;

namespace TestSecRulesLibrary
{
   public class TestArrayReadOnlyRule
   {
      [STAThread]
      public static void Main() 
      {
         MyClassWithReadOnlyArrayField dataHolder = 
            new MyClassWithReadOnlyArrayField();

         // Get references to the library's readonly arrays.
         int[] theGrades = dataHolder.grades;
         int[] thePrivateGrades = dataHolder.GetPrivateGrades();
         int[] theSecureGrades = dataHolder.GetSecurePrivateGrades();

         Console.WriteLine(
            "Before tampering: {0}", dataHolder.ToString());

         // Overwrite the contents of the "readonly" array. 
         theGrades[1]= 555;
         thePrivateGrades[1]= 555;
         theSecureGrades[1]= 555;
         Console.WriteLine(
            "After tampering: {0}",dataHolder.ToString());
      }
   }
}

Bu örnekten alınan çıkış:

Before tampering: Grades: 90, 90, 90 Private Grades: 90, 90, 90  Secure Grades, 90, 90, 90
After tampering: Grades: 90, 555, 90 Private Grades: 90, 555, 90  Secure Grades, 90, 90, 90

Ayrıca bkz.