CA2105 : Les champs de tableau ne doivent pas être en lecture seuleCA2105: Array fields should not be read only

TypeNameTypeName ArrayFieldsShouldNotBeReadOnlyArrayFieldsShouldNotBeReadOnly
CheckIdCheckId CA2105CA2105
CategoryCategory Microsoft.SecurityMicrosoft.Security
Modification avec ruptureBreaking Change RuptureBreaking

CauseCause

Un champ public ou protégé qui contient un tableau est déclaré en lecture seule.A public or protected field that holds an array is declared read-only.

Description de la règleRule Description

Lorsque vous appliquez le readonly (ReadOnly dans Visual BasicVisual Basic) modificateur à un champ qui contient un tableau, le champ ne peut pas être modifié pour faire référence à un tableau différent.When you apply the readonly (ReadOnly in Visual BasicVisual Basic) modifier to a field that contains an array, the field cannot be changed to refer to a different array. Toutefois, les éléments du tableau stockés dans un champ en lecture seule peuvent être modifiés.However, the elements of the array that are stored in a read-only field can be changed. Code qui prend des décisions ou exécute des opérations qui reposent sur les éléments d’un tableau en lecture seule accessible publiquement peut présenter une faille de sécurité exploitable.Code that makes decisions or performs operations that are based on the elements of a read-only array that can be publicly accessed might contain an exploitable security vulnerability.

Notez que la présence d’un champ public viole également la règle de conception CA1051 : ne pas déclarer de champs d’instances visibles.Note that having a public field also violates the design rule CA1051: Do not declare visible instance fields.

Comment corriger les violationsHow to Fix Violations

Pour résoudre le problème de sécurité est identifié par cette règle, ne comptez pas sur le contenu d’un tableau en lecture seule accessible publiquement.To fix the security vulnerability that is identified by this rule, do not rely on the contents of a read-only array that can be publicly accessed. Il est fortement recommandé d’utiliser l’une des procédures suivantes :It is strongly recommended that you use one of the following procedures:

  • Remplacez le tableau par une collection fortement typée qui ne peut pas être modifiée.Replace the array with a strongly typed collection that cannot be changed. Pour plus d'informations, consultez System.Collections.ReadOnlyCollectionBase.For more information, see System.Collections.ReadOnlyCollectionBase.

  • Remplacez le champ public avec une méthode qui retourne un clone d’un tableau privé.Replace the public field with a method that returns a clone of a private array. Étant donné que votre code ne repose pas sur le clone, il n’existe aucun risque si les éléments sont modifiés.Because your code does not rely on the clone, there is no danger if the elements are modified.

    Si vous avez choisi la deuxième approche, ne remplacez pas le champ avec une propriété ; propriétés qui retournent des tableaux pourrait-elle affectent les performances.If you chose the second approach, do not replace the field with a property; properties that return arrays adversely affect performance. Pour plus d’informations, consultez CA1819 : propriétés ne doivent pas retourner de tableaux.For more information, see CA1819: Properties should not return arrays.

Quand supprimer les avertissementsWhen to Suppress Warnings

Exclusion d’un avertissement de cette règle est fortement déconseillée.Exclusion of a warning from this rule is strongly discouraged. Pratiquement aucun scénario se produire lorsque le contenu d’un champ en lecture seule est sans importance.Almost no scenarios occur where the contents of a read-only field are unimportant. Si c’est le cas dans votre scénario, supprimez le readonly modificateur au lieu d’exclure le message.If this is the case with your scenario, remove the readonly modifier instead of excluding the message.

ExempleExample

Cet exemple illustre les risques de violation de cette règle.This example demonstrates the dangers of violating this rule. La première partie présente un exemple de bibliothèque qui a un type, MyClassWithReadOnlyArrayField, qui contient deux champs (grades et privateGrades) qui ne sont pas sécurisées.The first part shows an example library that has a type, MyClassWithReadOnlyArrayField, that contains two fields (grades and privateGrades) that are not secure. Le champ grades est public et par conséquent vulnérable pour tout appelant.The field grades is public, and therefore vulnerable to any caller. Le champ privateGrades est privé, mais est toujours vulnérable, car il est retourné aux appelants par le GetPrivateGrades (méthode).The field privateGrades is private but is still vulnerable because it is returned to callers by the GetPrivateGrades method. Le securePrivateGrades champ est exposé de manière sécurisée par le GetSecurePrivateGrades (méthode).The securePrivateGrades field is exposed in a safe manner by the GetSecurePrivateGrades method. Il est déclaré comme privé pour suivre les pratiques d’une bonne conception.It is declared as private to follow good design practices. La deuxième partie montre le code qui modifie les valeurs stockées dans le grades et privateGrades membres.The second part shows code that changes values stored in the grades and privateGrades members.

L’exemple de bibliothèque de classe s’affiche dans l’exemple suivant.The example class library appears in the following example.

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

ExempleExample

Le code suivant utilise la bibliothèque de classes d’exemple pour illustrer les problèmes de sécurité de tableau en lecture seule.The following code uses the example class library to illustrate read-only array security issues.

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 :The output from this example is:

Avant la falsification : notes : 90, 90, 90 Notes privées : 90, 90, 90 Notes sécurisées, 90, 90, 90 après la falsification : notes : 90, 555, 90 Notes privées : 90, 555, 90 Notes sécurisées, 90, 90, 90Before 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 aussiSee Also

System.Array System.Collections.ReadOnlyCollectionBaseSystem.Array System.Collections.ReadOnlyCollectionBase