Partilhar via


Campos de matriz não devem ser lidos apenas

TypeName

ArrayFieldsShouldNotBeReadOnly

CheckId

CA2105

Category (Categoria)

Microsoft.segurança

Quebrando alterar

Quebrando

Causa

Um campo público ou protegido que mantém uma matriz é declarado somente leitura.

Descrição da regra

Quando você aplica o readonly (ReadOnly no Visual Basic) modificadora a um campo que contém uma matriz, o campo não pode ser alterada para se referir a um array diferente. No entanto, os elementos da matriz armazenada em um campo somente leitura podem ser alterados.Código que toma decisões ou executa operações com base nos elementos de uma matriz de somente leitura acessível publicamente pode conter uma vulnerabilidade de segurança pode ser explorada.

Observe que também ter um campo público viola a regra de design Não declarará campos de instância visível.

Como corrigir violações

Para corrigir a vulnerabilidade de segurança identificada por esta regra, não confie no Sumário de um array publicamente acessível somente leitura.É altamente recomendável que você use um dos seguintes procedimentos:

  • substituir matriz a uma coleção fortemente tipada que não pode ser alterada.Para mais informações, consulte: System.Collections.ReadOnlyCollectionBase.

  • Substitua o campo público com um método que retorna um clone de um particular array.Como seu código não depende do clone, não há nenhum perigo se os elementos forem modificados.

Se você escolher a segunda abordagem, não substitua o campo com uma propriedade; propriedades que retornam matrizes contrariamente afetam o desempenho.Para obter mais informações, consulte Propriedades não devem retornar arrays.

Quando suprimir avisos

Excluindo um aviso desta regra não é recomendável.Não há quase nenhum cenários em que o Sumário de um campo somente leitura é sem importância.Se esse for o caso com o seu cenário, remova o readonly modificador em vez de excluir a mensagem.

Exemplo

Este exemplo demonstra os perigos de violar a regra.A primeira parte mostra uma biblioteca de exemplo com um tipo, MyClassWithReadOnlyArrayField, () que contém dois camposgrades e privateGrades) que não são seguras. O campo grades é pública e, portanto, vulnerável a qualquer chamador. O campo privateGrades é particular, mas continuarão vulneráveis porque é retornado para os chamadores pela GetPrivateGrades método. The securePrivateGrades campo é exposto de maneira segura, o GetSecurePrivateGrades método. Ele é declarado sistema autônomo privado seguir práticas recomendadas de um mercadoria design.A segunda parte mostra o código que altera valores armazenados no grades e privateGrades membros.

A biblioteca de classes exemplo aparece no exemplo a seguir.

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

O código a seguir usa a biblioteca de classes de exemplo para ilustrar os problemas de segurança da matriz somente leitura.

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

A saída deste exemplo é:

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

Consulte também

Referência

System.Array

System.Collections.ReadOnlyCollectionBase