The SecurityRulesAttribute is a new attribute class introduced in .NET 4.0 to specify which set of security rules a particular assembly adheres to. The attribute is specified on the assembly level, and allows you to specify two pieces of information.
The first and more important piece is the version of transparency that your assembly follows. If you want to use the .NET 2.0 interpretation of transparency, specify SecurityRuleSet.Level1 as the argument to the SecurityRulesAttribute constructor. If you want to use the .NET 4.0 interpretation of transparency, specify SecurityRuleSet.Level2. Level2 is also the default for assemblies built on the .NET 4.0 runtime.
For CLRv2 transparency semantics:
[assembly: SecurityRules(SecurityRuleSet.Level1)]
For CLRv4 transparency semantics:
[assembly: SecurityRules(SecurityRuleSet.Level2)]
The second piece allows to tell the CLR that you want to skip IL verification of your assembly when it is fully trusted and transparent. Remember, transparent code can’t contain unverifiable code or P/Invokes, so the CLR usually must check that the transparent code it loads does not violate these invariants. You can skip this verification to increase your performance slightly when the JIT compiler compiles your code, but remember that doing this will allow unverifiable code in your assembly. I’d recommend using this only if you don’t have unverifiable code in your transparent assembly.
That last scenario is slightly abstract, so I want to show an example of the difference.
SecurityDriver.exe
public class Program : MarshalByRefObject
{
static void Main(string[] args)
{
PartialTrustSetup.CreatePartialTrustInstance<Program>().PartialTrustMain();
}
public void PartialTrustMain()
{
Utility u = new Utility();
u.ExecuteUnsafeCode();
}
}
SecurityLibrary.dll (Pardon the trivial example of unverifiable code.)
[assembly: SecurityTransparent]
public class Utility
{
public unsafe void ExecuteUnsafeCode()
{
int i = 0;
int* p = &i;
*p = 2;
Console.WriteLine(i);
}
}
The Main method in SecurityDriver.exe sets up a partial-trust AppDomain and instantiates a new instance of the Program class in that AppDomain. The partial trust code only has permission to execute (SecurityPermission with SecurityPermissionFlag.Execution). When it calls Utility.ExecuteUnsafeCode, the JIT compiler throws a VerificationException because it can’t verify the IL in Utility.ExecuteUnsafeCode.
But if we add this attribute to the SecurityLibrary assembly and ensure that it is fully trusted (by using the StrongName[] parameter of the AppDomain.CreateDomain method), then the JIT compiler will skip IL verification, and "2" will be printed to the console.
[assembly: SecurityRules(SecurityRuleSet.Level2, SkipVerificationInFullTrust = true)]
Remember, this only works when your transparent assembly is fully trusted.