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