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


CA2107: проверьте использование deny и permit only

TypeName

ReviewDenyAndPermitOnlyUsage

CheckId

CA2107

Категория

Microsoft.Security

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

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

Причина

Метод содержит проверку безопасности, которая задает действие безопасности PermitOnly или Deny.

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

Действия безопасности Использование метода PermitOnly и CodeAccessPermission.Deny могут использовать только пользователи, обладающие достаточными знаниями о безопасности .NET Framework. Код, который использует эти действия безопасности, должен быть тщательно проанализирован на предмет безопасности.

Действие безопасности Deny изменяет поведение прохода стека, заданное по умолчанию, которое возникает в ответ на запрос безопасности. Оно позволяет указать разрешения, которые не должны предоставляться в течение метода отказа, независимо от фактических разрешений вызывающих методов в стеке вызова. Если при проходе стека обнаруживается метод, защищенный действием Deny, и если запрашиваемое разрешение входит в число отклоненных разрешений, происходит сбой прохода стека. Действие безопасности PermitOnly изменяет поведение прохода стека, заданное по умолчанию. Оно позволяет коду указывать только те разрешения, которые могут быть предоставлены независимо от разрешений вызывающих методов. Если при проходе стека обнаруживается метод, защищенный действием PermitOnly, и если запрашиваемое разрешение не входит в число разрешений, указанных действием PermitOnly, происходит сбой прохода стека.

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

  • Действия Deny или PermitOnly не влияют на Требования связывания.

  • Если Deny или PermitOnly происходят в одном и том же фрейме стека, что и запрос, вызывающий проход стека, действия безопасности никак не отражаются.

  • Значения, используемые для формирования основанных на путях разрешений, обычно можно указать несколькими способами. Запрет доступа к одной форме пути не запрещает доступ ко всем формам. Например, если общий ресурс \\Server\Share назначен на сетевой диск X:, то для запрета доступа к файлу в общей папке необходимо запретить \\Server\Share\File, X:\File и все остальные пути, обращающиеся к файлу.

  • CodeAccessPermission.Assert может остановить проход стека, прежде чем будут достигнуты Deny или PermitOnly.

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

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

Любое использование этих действий безопасности вызовет нарушение. Устранить нарушение можно, если не использовать эти действия безопасности.

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

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

Пример

В следующем примере показаны некоторые ограничения действия Deny.

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

using System.Security;
using System.Security.Permissions;
using System;

namespace SecurityRulesLibrary
{
   public  class SomeSecuredMethods
   {

      // Demand immediate caller has suitable permission
      // before revealing sensitive data.
      [EnvironmentPermissionAttribute(SecurityAction.LinkDemand,
          Read="COMPUTERNAME;USERNAME;USERDOMAIN")]

      public static void MethodProtectedByLinkDemand()
      {
         Console.Write("LinkDemand: ");
      }

      [EnvironmentPermissionAttribute(SecurityAction.Demand,
          Read="COMPUTERNAME;USERNAME;USERDOMAIN")]

      public static void MethodProtectedByDemand()
      {
         Console.Write("Demand: ");
      }
   }
}

В следующем приложении демонстрируется действие Deny с защищенными методами из библиотеки.

using System.Security;
using System.Security.Permissions;
using System;
using SecurityRulesLibrary;

namespace TestSecurityLibrary
{
    // Violates rule: ReviewDenyAndPermitOnlyUsage.
   public class TestPermitAndDeny
   {
      public static void TestAssertAndDeny()
      {
         EnvironmentPermission envPermission = new EnvironmentPermission(
               EnvironmentPermissionAccess.Read,
               "COMPUTERNAME;USERNAME;USERDOMAIN");
         envPermission.Assert();
         try
         {
            SomeSecuredMethods.MethodProtectedByDemand();
            Console.WriteLine(
               "Caller's Deny has no effect on Demand " + 
               "with the asserted permission.");

            SomeSecuredMethods.MethodProtectedByLinkDemand();
            Console.WriteLine(
               "Caller's Deny has no effect on LinkDemand " + 
               "with the asserted permission.");
         }
         catch (SecurityException e)
         {
            Console.WriteLine(
               "Caller's Deny protected the library.{0}", e);
         }
      }

      public static void TestDenyAndLinkDemand()
      {
         try
         {
            SomeSecuredMethods.MethodProtectedByLinkDemand();
            Console.WriteLine(
               "Caller's Deny has no effect with " +
               "LinkDemand-protected code.");
         }
         catch (SecurityException e)
         {
            Console.WriteLine(
               "Caller's Deny protected the library.{0}",e);
         }
      }

      public static void Main()
      {
         EnvironmentPermission envPermission = new EnvironmentPermission(
            EnvironmentPermissionAccess.Read,
            "COMPUTERNAME;USERNAME;USERDOMAIN");
         envPermission.Deny();

         //Test Deny and Assert interaction for LinkDemands and Demands.
         TestAssertAndDeny();

         //Test Deny's effects on code in different stack frame. 
         TestDenyAndLinkDemand();

         //Test Deny's effect on code in same frame as deny.
         try
         {
            SomeSecuredMethods.MethodProtectedByLinkDemand();
            Console.WriteLine(
               "This Deny has no effect with LinkDemand-protected code.");
         }
         catch (SecurityException e)
         {
            Console.WriteLine("This Deny protected the library.{0}",e);
         }
      }
   }
}

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

          

См. также

Ссылки

CodeAccessPermission.PermitOnly

CodeAccessPermission.Assert

CodeAccessPermission.Deny

IStackWalk.PermitOnly

Основные понятия

Правила написания безопасного кода

Переопределение результатов проверки безопасности

Использование метода PermitOnly