Поделиться через


CA2119: запечатайте методы, соответствующие частным интерфейсам

TypeName

SealMethodsThatSatisfyPrivateInterfaces

CheckId

CA2119

Категория

Microsoft.Security

Критическое изменение

Критическое изменение

Причина

Наследуемый отрытый тип предоставляет реализацию переопределяемого метода интерфейса internal (Friend в Visual Basic).

Описание правила

Методы интерфейса являются открытыми для доступа, чего нельзя изменить путем реализации типа. Внутренний интерфейс создает контракт, который не предназначен для реализации вне сборки, определяющей интерфейс. Открытый тип, реализующий метод внутреннего интерфейса при помощи модификатора virtual (Overridable в Visual Basic) позволяет переопределять метод производным типам, находящимся вне сборки. Если второй тип в определяющей сборке вызывает метод и требует только внутреннего контракта, поведение может быть нарушено, если будет выполнен переопределенный метод во внешней сборке. Это создает уязвимость безопасности.

Устранение нарушений

Чтобы устранить нарушение этого правила, избегайте переопределения метода вне сборки, выполнив одно из следующих действий.

  • Сделайте объявляющий тип sealed (NotInheritable в Visual Basic).

  • Измените доступность объявляющего типа на internal (Friend в Visual Basic).

  • Удалите все открытые конструкторы из объявляющего типа.

  • Реализуйте метод без модификатора virtual.

  • Реализуйте метод явным образом.

Отключение предупреждений

Предупреждение из этого правила можно отключить без последствий при условии, что после тщательного анализа отсутствуют угрозы безопасности, которые могли бы быть использованы, если бы метод переопределялся вне сборки.

Пример

В следующем примере показан тип BaseImplementation, который нарушает данное правило.

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

В следующем примере используется реализация виртуального метода из предыдущего примера.

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

См. также

Ссылки

Интерфейсы (Руководство по программированию в C#)

Другие ресурсы

Интерфейсы (Visual Basic)