CA2105 : Les champs de tableau ne doivent pas être en lecture seule

Élément Valeur
ID de la règle CA2105
Category Microsoft.Security
Modification avec rupture Rupture

Cause

Un champ public ou protégé qui contient un tableau est déclaré en lecture seule.

Notes

Cette règle est déconseillée. Pour plus d’informations, consultez Règles dépréciées.

Description de la règle

Lorsque vous appliquez le modificateur readonly (ReadOnly en Visual Basic) à un champ qui contient un tableau, ce champ ne peut pas être modifié pour référencer un tableau différent. Toutefois, les éléments du tableau stockés dans un champ en lecture seule peuvent être modifiés. Le code qui prend des décisions ou effectue des opérations basées sur les éléments d’un tableau en lecture seule accessible publiquement peut contenir une vulnérabilité de sécurité exploitable.

Notez que le fait d’avoir un champ public enfreint également la règle de conception CA1051 : Ne déclarez pas de champs d’instances visibles.

Comment corriger les violations

Pour corriger la vulnérabilité de sécurité identifiée par cette règle, ne vous appuyez pas sur le contenu d’un tableau en lecture seule accessible publiquement. Il est vivement recommandé d’utiliser l’une des procédures suivantes :

  • Remplacez le tableau par une collection fortement typée qui ne peut pas être modifiée. Pour plus d’informations, consultez System.Collections.ReadOnlyCollectionBase.

  • Remplacez le champ public par une méthode qui retourne un clone d’un tableau privé. Étant donné que votre code ne repose pas sur le clone, il n’y a aucun danger si les éléments sont modifiés.

Si vous avez choisi la deuxième approche, ne remplacez pas le champ par une propriété ; les propriétés qui retournent des tableaux ont un impact négatif sur les performances. Pour plus d’informations, consultez CA1819 : Les propriétés ne doivent pas retourner des tableaux.

Quand supprimer les avertissements

L’exclusion d’un avertissement de cette règle est fortement déconseillée. Quasiment aucun scénario ne se produit où le contenu d’un champ en lecture seule n’est pas important. Si c’est le cas avec votre scénario, supprimez le modificateur readonly au lieu d’exclure le message.

Exemple 1

Cet exemple illustre les dangers de la violation de cette règle. La première partie montre un exemple de bibliothèque qui a un type, MyClassWithReadOnlyArrayFieldqui contient deux champs (grades et privateGrades) qui ne sont pas sécurisés. Le champ grades est public et donc vulnérable à n’importe quel appelant. Le champ privateGrades est privé, mais reste vulnérable, car il est retourné aux appelants par la méthode GetPrivateGrades. Le champ securePrivateGrades est exposé de manière sécurisée par la méthode GetSecurePrivateGrades. Il est déclaré privé pour suivre les bonnes pratiques de conception. La deuxième partie montre le code qui modifie les valeurs stockées dans les membres grades et privateGrades.

L’exemple de bibliothèque de classes apparaît dans l’exemple suivant.

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

Exemple 2

Le code suivant utilise l’exemple de bibliothèque de classes pour illustrer les problèmes de sécurité de tableau en lecture seule.

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

La sortie de cet exemple est :

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

Voir aussi