CA2107:检查 deny 权限和 permit only 权限的使用情况

“值”
RuleId CA2107
Category Microsoft.Security
重大更改 重大

原因

包含安全检查的一个方法,该检查指定 PermitOnly 或 Deny 安全操作。

注意

此规则已被弃用。 有关详细信息,请参阅已弃用的规则

规则说明

System.Security.CodeAccessPermission.Deny 安全操作只能由掌握 .NET 安全高级知识的人员使用。 应当对使用这些安全操作的代码进行安全检查。

Deny 会更改响应安全需求时发生的堆栈审核的默认行为。 它可以指定在拒绝方法的持续时间内不得授予的权限,且无需考虑调用堆栈中调用方所拥有的实际权限。 如果堆栈审核检测到 Deny 保护的方法,并且如果拒绝的权限中包含所需的权限,则堆栈审核失败。 PermitOnly 还会改变堆栈审核的默认行为。 代码通过它可以只指定可授予的权限,且无需考虑调用方所拥有的权限。 如果堆栈审核检测到 PermitOnly 保护的方法,并且如果 PermitOnly 指定的权限中未包含所需的权限,则堆栈审核失败。

应仔细评估依赖于这些操作的代码是否存在安全漏洞,因为这些操作用处有限且有害。 考虑以下情况:

  • 链接需求不受 Deny 或 PermitOnly 的影响。

  • 如果 Deny 或 PermitOnly 与导致堆栈审核的需求出现在同一堆栈帧中,则安全操作无效。

  • 通常可以通过多种方式指定用于构造基于路径的权限的值。 拒绝访问某一种形式的路径并不会拒绝访问所有形式的路径。 例如,如果文件共享 \\Server\Share 映射到网络驱动器 X:,若要拒绝访问该共享上的文件,则必须拒绝 \\Server\Share\File、X:\File 以及可访问该文件的所有其他路径。

  • System.Security.CodeAccessPermission.Assert 可以在达到 Deny 或 PermitOnly 之前终止堆栈审核。

  • 如果 Deny 产生任何效果,即当调用方拥有 Deny 所阻止的权限时,调用方可以绕过 Deny 直接访问受保护的资源。 同样,如果调用方没有遭拒绝的权限,则堆栈审核将因没有 Deny 而失败。

如何解决冲突

只要执行这些安全操作就会导致违规。 若要避免违规,请勿执行这些安全操作。

何时禁止显示警告

完成安全审查后才能禁止显示来自此规则的警告。

示例 1

以下示例演示 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: ");
      }
   }
}

示例 2

以下应用程序演示 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);
         }
      }
   }
}

该示例产生下面的输出:

Demand: Caller's Deny has no effect on Demand with the asserted permission.
LinkDemand: Caller's Deny has no effect on LinkDemand with the asserted permission.
LinkDemand: Caller's Deny has no effect with LinkDemand-protected code.
LinkDemand: This Deny has no effect with LinkDemand-protected code.

另请参阅