Do not indirectly expose methods with link demands
TypeName |
DoNotIndirectlyExposeMethodsWithLinkDemands |
CheckId |
CA2122 |
Category |
Microsoft.Security |
Breaking Change |
NonBreaking |
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 Access or link demand to the member so that it no longer provides unsecured access to the link demand-protected member.
When to Exclude Warnings
To safely exclude a warning from this rule, you must ensure 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 calling 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.
Output
Value from unsecured member: seattle.corp.contoso.com