CA2122:不要使用链接请求间接公开方法

类型名

DoNotIndirectlyExposeMethodsWithLinkDemands

CheckId

CA2122

类别

Microsoft.Security

是否重大更改

原因

公共或受保护成员具有 链接需求,且是由不执行任何安全检查的成员调用的。

规则说明

链接请求仅检查直接调用方的权限。 如果成员 X 不发出其调用方的安全请求,并调用受链接请求保护的代码,则没有必需权限的调用方可使用 X 访问受保护成员。

如何解决冲突

向成员添加安全 数据访问和建模 或链接请求,使其不再提供对受链接请求保护的成员的不安全访问。

何时禁止显示警告

若要安全禁止显示此规则发出的警告,必须确保您的代码不会授予其调用方对可通过破坏性方式使用的操作或资源的访问权限。

示例

下面的示例显示一个与该规则冲突的库以及一个演示该库漏洞的应用程序。 示例库提供一起与该规则冲突的两个方法。 EnvironmentSetting 方法受链接请求保护,可无限制地访问环境变量。 DomainInformation 方法在调用 EnvironmentSetting 之前,不会对其调用方提出任何安全请求。

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

namespace SecurityRulesLibrary
{
   public class DoNotIndirectlyExposeMethodsWithLinkDemands
   {
      // Violates rule: DoNotIndirectlyExposeMethodsWithLinkDemands.
      public static string DomainInformation()
      {
         return EnvironmentSetting("USERDNSDOMAIN");
      }

      // Library method with link demand.
      // This method holds its immediate callers responsible for securing the information.
      // Because a caller must have unrestricted permission, the method asserts read permission
      // in case some caller in the stack does not have this permission. 

      [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
      public static string EnvironmentSetting(string environmentVariable)
      {
         EnvironmentPermission envPermission = new EnvironmentPermission( EnvironmentPermissionAccess.Read,environmentVariable);
         envPermission.Assert();

         return Environment.GetEnvironmentVariable(environmentVariable);
      }
   }
}

下面的应用程序调用不安全的库成员。

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

// You have no permission to access the sensitive information,
// but you will get data from the unprotected method.
[assembly:EnvironmentPermissionAttribute(
   SecurityAction.RequestRefuse,Unrestricted=true)]
namespace TestUnsecuredMembers
{
   class TestUnsecured
   {
      [STAThread]
      static void Main(string[] args)
      {
         string value = null;
         try 
         {
            value = DoNotIndirectlyExposeMethodsWithLinkDemands.DomainInformation();
         }
         catch (SecurityException e) 
         {
            Console.WriteLine(
               "Call to unsecured member was stopped by code access security! {0}",
               e.Message);
            throw;
         }
         if (value != null) 
         {
            Console.WriteLine("Value from unsecured member: {0}", value);
         }
      }
   }
}

该示例产生下面的输出。

  

请参见

概念

代码安全维护指南

链接需求

其他资源

数据访问和建模