CS.SV.TRANSP.ASSERT
Transparent methods may not use security asserts.
This rule analyzes all methods and types in an assembly which is either 100% transparent or mixed transparent/critical, and flags any declarative or imperative usage of Assert. At run time, any calls to Assert from transparent code will cause a InvalidOperationException to be thrown.
This can occur in both 100% transparent assemblies, and also in mixed transparent/critical assemblies where a method or type is declared transparent, but includes a declarative or imperative Assert. The .NET Framework 2.0 introduced a feature named transparency. Individual methods, fields, interfaces, classes, and types can be either transparent or critical.
Transparent code is not allowed to elevate security privileges. Therefore, any permissions granted or demanded of it are automatically passed through the code to the caller or host application domain. Examples of elevations include Asserts, LinkDemands, SuppressUnmanagedCode, and unsafe code.
Vulnerable code example
using System;
using System.Security;
using System.Security.Permissions;
namespace TransparencyWarningsDemo
{
public class TransparentMethodsUseSecurityAssertsClass
{
// CA2147 violation - transparent code using a security assert declaratively. This can be fixed by
// any of:
// 1. Make DeclarativeAssert critical
// 2. Make DeclarativeAssert safe critical
// 3. Remove the assert attribute
[PermissionSet(SecurityAction.Assert, Unrestricted = true)]
public void DeclarativeAssert()
{
}
public void ImperativeAssert()
{
// CA2147 violation - transparent code using a security assert imperatively. This can be fixed by
// any of:
// 1. Make ImperativeAssert critical
// 2. Make ImperativeAssert safe critical
// 3. Remove the assert call
new PermissionSet(PermissionState.Unrestricted).Assert();
}
}
}
This code will fail if SecurityTestClass is transparent, when the Assert method throws a InvalidOperationException.
Fixed code example
using System;
using System.Security.Permissions;
namespace SecurityTestClassLibrary
{
public class SecurityTestClass
{
[System.Security.SecurityCritical]
void SecurityCriticalMethod()
{
new FileIOPermission(PermissionState.Unrestricted).Assert();
// perform I/O operations under Assert
}
}
}
One option is to code review the SecurityTransparentMethod method in the example, and if the method is considered safe for elevation, mark SecurityTransparentMethod with secure-critical. This requires that a detailed, complete, and error-free security audit is performed on the method, together with any call-outs that occur within the method under the Assert.
Another option is to remove the Assert from the code, and let any subsequent file I/O permission demands flow beyond SecurityTransparentMethod to the caller. This enables security checks. In this case, no security audit is needed, because the permission demands will flow to the caller and/or the application domain. Permission demands are closely controlled through security policy, hosting environment, and code-source permission grants.