Partager via


CA2119 : Scellez les méthodes qui satisfont les interfaces privées

TypeName

SealMethodsThatSatisfyPrivateInterfaces

CheckId

CA2119

Catégorie

Microsoft.Security

Modification avec rupture

Oui

Cause

Un type public pouvant être hérité fournit une implémentation de méthode pouvant être substituée d'une interface internal (Friend en Visual Basic).

Description de la règle

Les méthodes d'interface disposent d'une accessibilité publique, qui ne peut pas être modifiée par le type d'implémentation. Une interface interne crée un contrat qui n'est pas destiné à être implémenté à l'extérieur de l'assembly qui définit l'interface. Un type public qui implémente une méthode d'une interface interne à l'aide du modificateur virtual (Overridable en Visual Basic) autorise la substitution de la méthode par un type dérivé situé à l'extérieur de l'assembly. Si un deuxième type dans l'assembly de définition appelle la méthode et s'attend à un contrat interne uniquement, le comportement peut être compromis lorsque la méthode substituée dans l'assembly externe est exécutée. Cela crée une faille de sécurité.

Comment corriger les violations

Pour corriger une violation de cette règle, empêchez la substitution de la méthode à l'extérieur de l'assembly à l'aide de l'une des méthodes suivantes :

  • Créez le type déclarant sealed (NotInheritable en Visual Basic).

  • Remplacez l'accessibilité du type déclarant par internal (Friend en Visual Basic).

  • Supprimez tous les constructeurs publics du type déclarant.

  • Implémentez la méthode sans utiliser le modificateur virtual.

  • Implémentez explicitement la méthode.

Quand supprimer les avertissements

Il est possible de supprimer sans risque un avertissement de cette règle si, après examen minutieux, aucun problème de sécurité, qui peut être exploitable si la méthode est substituée à l'extérieur de l'assembly, n'est détecté.

Exemple

L'exemple suivant présente un type, BaseImplementation, qui ne respecte pas cette règle.

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.");
         }
      }
   };
}

L'exemple suivant exploite l'implémentation de méthode virtuelle de l'exemple précédent.

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.");
         }
      }
   };
}

Voir aussi

Référence

Interfaces (Guide de programmation C#)

Autres ressources

Interfaces (Visual Basic)