Condividi tramite


CA2119: Impostare come sealed i metodi che soddisfano interfacce private

TypeName

SealMethodsThatSatisfyPrivateInterfaces

CheckId

CA2119

Category

Microsoft.Security

Breaking Change

Breaking

Causa

Un tipo pubblico ereditabile fornisce un'implementazione di metodo sottoponibile a override di un'interfaccia internal (Friend in Visual Basic).

Descrizione della regola

I metodi dell'interfaccia dispongono di accessibilità pubblica, che non è possibile modificare mediante il tipo di implementazione.Un'interfaccia interna crea un contratto di cui non è prevista l'implementazione all'esterno dell'assembly che definisce l'interfaccia.Un tipo pubblico che implementa un metodo di un'interfaccia interna mediante il modificatore virtual (Overridable in Visual Basic) consente di eseguire l'override del metodo con un tipo derivato che si trova all'esterno dell'assembly.Se un secondo tipo nell'assembly di definizione chiama il metodo e prevede un contratto solo interno, è possibile che il comportamento risulti compromesso quando il metodo sottoposto a override nell'assembly esterno viene invece eseguito.In tal modo viene creata una vulnerabilità della sicurezza.

Come correggere le violazioni

Per correggere una violazione di questa regola, impedire che venga eseguito l'override del metodo esternamente all'assembly utilizzando una delle soluzioni illustrate di seguito:

  • Rendere sealed (NotInheritable in Visual Basic) il tipo di dichiarazione.

  • Modificare l'accessibilità del tipo di dichiarazione in internal (Friend in Visual Basic).

  • Rimuovere tutti i costruttori pubblici dal tipo di dichiarazione.

  • Implementare il metodo senza utilizzare il modificatore virtual.

  • Implementare il metodo in maniera esplicita.

Esclusione di avvisi

È sicuro escludere un avviso da questa regola se dopo un attento esame risulterà che non potranno derivare problemi di sicurezza se verrà eseguito l'override del metodo esterno all'assembly.

Esempio

Nell'esempio riportato di seguito viene illustrato un tipo, BaseImplementation, che viola questa regola.

Imports System

Namespace SecurityLibrary

   Interface IValidate
      Function UserIsValidated() As Boolean 
   End Interface 

   Public Class BaseImplementation
      Implements IValidate

      Overridable Function UserIsValidated() As Boolean _ 
         Implements IValidate.UserIsValidated
         Return False 
      End Function 

   End Class 

   Public Class UseBaseImplementation

      Sub SecurityDecision(someImplementation As BaseImplementation)

         If(someImplementation.UserIsValidated() = True)
            Console.WriteLine("Account number & balance.")
         Else
            Console.WriteLine("Please login.")
         End If 

      End Sub 

   End Class 

End Namespace
using System;

namespace SecurityLibrary
{
   // Internal by default. 
   interface IValidate
   {
      bool UserIsValidated();
   }

   public class BaseImplementation : IValidate
   {
      public virtual bool UserIsValidated()
      {
         return false;
      }
   }

   public class UseBaseImplementation
   {
      public void SecurityDecision(BaseImplementation someImplementation)
      {
         if(someImplementation.UserIsValidated() == true)
         {
            Console.WriteLine("Account number & balance.");
         }
         else
         {
            Console.WriteLine("Please login.");
         }
      }
   }
}
using namespace System;

namespace SecurityLibrary
{
   // Internal by default. 
   interface class IValidate
   {
      bool UserIsValidated();
   };

   public ref class BaseImplementation : public IValidate
   {
   public:
      virtual bool UserIsValidated()
      {
         return false;
      }
   };

   public ref class UseBaseImplementation
   {
   public:
      void SecurityDecision(BaseImplementation^ someImplementation)
      {
         if(someImplementation->UserIsValidated() == true)
         {
            Console::WriteLine("Account number & balance.");
         }
         else
         {
            Console::WriteLine("Please login.");
         }
      }
   };
}

Nell'esempio seguente viene utilizzata l'implementazione del metodo virtuale dell'esempio precedente:

Imports System

Namespace SecurityLibrary

   Public Class BaseImplementation

      Overridable Function UserIsValidated() As Boolean 
         Return False 
      End Function 

   End Class 

   Public Class UseBaseImplementation

      Sub SecurityDecision(someImplementation As BaseImplementation)

         If(someImplementation.UserIsValidated() = True)
            Console.WriteLine("Account number & balance.")
         Else
            Console.WriteLine("Please login.")
         End If 

      End Sub 

   End Class 

End Namespace
using System;

namespace SecurityLibrary
{
    public class BaseImplementation 
    {
        public virtual bool UserIsValidated()
        {
            return false;
        }
    }

    public class UseBaseImplementation
    {
        public void SecurityDecision(BaseImplementation someImplementation)
        {
            if (someImplementation.UserIsValidated() == true)
            {
                Console.WriteLine("Account number & balance.");
            }
            else
            {
                Console.WriteLine("Please login.");
            }
        }
    }
}
using namespace System;

namespace SecurityLibrary
{
   public ref class BaseImplementation
   {
   public:
      virtual bool UserIsValidated()
      {
         return false;
      }
   };

   public ref class UseBaseImplementation
   {
   public:
      void SecurityDecision(BaseImplementation^ someImplementation)
      {
         if(someImplementation->UserIsValidated() == true)
         {
            Console::WriteLine("Account number & balance.");
         }
         else
         {
            Console::WriteLine("Please login.");
         }
      }
   };
}

Vedere anche

Riferimenti

Interfacce (Guida per programmatori C#)

Altre risorse

Interfacce (Visual Basic)