CA2122: Do not indirectly expose methods with link demands

TypeName

DoNotIndirectlyExposeMethodsWithLinkDemands

CheckId

CA2122

Category

Microsoft.Security

Breaking Change

Non Breaking

Cause

A public or protected member has a Link Demands and is called by a member that does not perform any security checks.

Rule Description

A link demand checks the permissions of the immediate caller only. If a member X makes no security demands of its callers, and calls code protected by a link demand, a caller without the necessary permission can use X to access the protected member.

How to Fix Violations

Add a security Data and Modeling in the .NET Framework or link demand to the member so that it no longer provides unsecured access to the link demand-protected member.

When to Suppress Warnings

To safely suppress a warning from this rule, you must make sure that your code does not grant its callers access to operations or resources that can be used in a destructive manner.

Example

The following examples show a library that violates the rule, and an application that demonstrates the library's weakness. The sample library provides two methods that together violate the rule. The EnvironmentSetting method is secured by a link demand for unrestricted access to environment variables. The DomainInformation method makes no security demands of its callers before it calls 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);
      }
   }
}

The following application calls the unsecured library member.

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

This example produces the following output.

Value from unsecured member: seattle.corp.contoso.com

See Also

Concepts

Link Demands

Other Resources

Secure Coding Guidelines

Data and Modeling in the .NET Framework