CA2123: Override link demands should be identical to base

TypeName

OverrideLinkDemandsShouldBeIdenticalToBase

CheckId

CA2123

Category

Microsoft.Security

Breaking Change

Breaking

Cause

A public or protected method in a public type overrides a method or implements an interface, and does not have the same Link Demands as the interface or virtual method.

Rule Description

This rule matches a method to its base method, which is either an interface or a virtual method in another type, and then compares the link demands on each. A violation is reported if either the method or the base method has a link demand and the other does not.

If this rule is violated, a malicious caller can bypass the link demand merely by calling the unsecured method.

How to Fix Violations

To fix a violation of this rule, apply the same link demand to the overide method or implementation. If this is not possible, mark the method with a full demand or remove the attribute altogether.

When to Suppress Warnings

Do not suppress a warning from this rule.

Example

The following example shows various violations of this rule.

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

namespace SecurityRulesLibrary
{
   public interface ITestOverrides
   {  
      [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
      Object GetFormat(Type formatType);
   }

   public class OverridesAndSecurity : ITestOverrides
   {
      // Rule violation: The interface has security, and this implementation does not. 
      object ITestOverrides.GetFormat(Type formatType)
      {
         return (formatType == typeof(OverridesAndSecurity) ? this : null);
      }

      // These two methods are overridden by DerivedClass and DoublyDerivedClass.
      [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
      public virtual void DoSomething()
      {
         Console.WriteLine("Doing something.");
      }

      public virtual void DoSomethingElse()
      {
         Console.WriteLine("Doing some other thing.");
      }
   }

   public class DerivedClass : OverridesAndSecurity, ITestOverrides
   {
      //  Rule violation: The interface has security, and this implementation does not. 
      public object GetFormat(Type formatType)
      {
         return (formatType == typeof(OverridesAndSecurity) ? this : null);
      }

      // Rule violation: This does not have security, but the base class version does. 
      public override void DoSomething()
      {
         Console.WriteLine("Doing some derived thing.");
      }

      // Rule violation: This has security, but the base class version does not.
      [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
      public override void DoSomethingElse()
      {
         Console.WriteLine("Doing some other derived thing.");
      }
   }

   public class DoublyDerivedClass : DerivedClass
   {
      // The OverridesAndSecurity version of this method does not have security.  
      // Base class DerivedClass's version does.  
      // The DoublyDerivedClass version does not violate the rule, but the  
      // DerivedClass version does violate the rule. 
      public override void DoSomethingElse()
      {
         Console.WriteLine("Doing some other derived thing.");
      }
   }
}

See Also

Concepts

Link Demands

Other Resources

Secure Coding Guidelines