Share via


CA2105: I campi di matrici non devono essere di sola lettura

Articolo Valore
ID regola CA2105
Category Microsoft.Security
Modifica Interruzione

Causa

Un campo pubblico o protetto che contiene una matrice è dichiarato di sola lettura.

Nota

Questa regola è stata deprecata. Per altre informazioni, vedere Regole deprecate.

Descrizione regola

Quando si applica il readonly modificatore (ReadOnly in Visual Basic) a un campo contenente una matrice, il campo non può essere modificato per fare riferimento a una matrice diversa. È tuttavia possibile modificare gli elementi della matrice archiviati in un campo in sola lettura. Il codice che prende decisioni o esegue operazioni basate sugli elementi di una matrice di sola lettura a cui è possibile accedere pubblicamente potrebbe contenere una vulnerabilità di sicurezza sfruttabile.

Si noti che la presenza di un campo pubblico viola anche la regola di progettazione CA1051: Non dichiarare campi di istanza visibili.

Come correggere le violazioni

Per correggere la vulnerabilità di sicurezza identificata da questa regola, non basarsi sul contenuto di una matrice di sola lettura a cui è possibile accedere pubblicamente. È consigliabile utilizzare una delle procedure seguenti:

  • Sostituire la matrice con una raccolta fortemente tipizzata che non può essere modificata. Per ulteriori informazioni, vedere System.Collections.ReadOnlyCollectionBase.

  • Sostituire il campo pubblico con un metodo che restituisce un clone di una matrice privata. Poiché il codice non si basa sul clone, non esiste alcun pericolo se gli elementi vengono modificati.

Se si sceglie il secondo approccio, non sostituire il campo con una proprietà ; le proprietà che restituiscono matrici influiscono negativamente sulle prestazioni. Per altre informazioni, vedere CA1819: Proprietà non devono restituire matrici.

Quando eliminare gli avvisi

L'esclusione di un avviso da questa regola è fortemente sconsigliata. Quasi nessun scenario si verifica quando il contenuto di un campo di sola lettura non è importante. Se questo è il caso dello scenario, rimuovere il readonly modificatore invece di escludere il messaggio.

Esempio 1

In questo esempio vengono illustrati i pericoli di violazione di questa regola. La prima parte mostra una libreria di esempio con un tipo , MyClassWithReadOnlyArrayField, che contiene due campi (grades e privateGrades) che non sono sicuri. Il campo grades è pubblico e quindi vulnerabile a qualsiasi chiamante. Il campo privateGrades è privato ma è ancora vulnerabile perché viene restituito ai chiamanti dal GetPrivateGrades metodo . Il securePrivateGrades campo viene esposto in modo sicuro dal GetSecurePrivateGrades metodo . Viene dichiarato come privato per seguire le procedure di progettazione consigliate. La seconda parte mostra il codice che modifica i grades valori archiviati nei membri e privateGrades .

La libreria di classi di esempio viene visualizzata nell'esempio seguente.

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

Esempio 2

Il codice seguente usa la libreria di classi di esempio per illustrare i problemi di sicurezza della matrice di sola lettura.

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

L'output di questo esempio è:

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

Vedi anche