Be very careful with the .NET Security Identity permissions that you may be using in your code, when planning to migrate the code base to .NET 2.0+, especially the StrongNameIdentityPermission (SNIP)
When you have SNIP .NET CAS identity permission being used on any of your highly privileged code, and require that all calling code (including FullTrust code) calling on this SNIP’d method(s) to have strong name signed using the same key as is in the called code, you may be feeling warm and cosy thinking that you may have completely secured all external access to your code.
Your assumption stands true in a .NET 1.1 CAS Security context, but not in the .NET 2.0 CAS context.
What is happening is that in .NET 1.1, unlike most other CAS permission classes which implements IUnrestrictedPermission interface, the CAS Identity permissions cannot have the Unrestricted permission state value set up on them.
Since the Identity permission do not implement this interface, nor otherwise allow the Unrestricted state value to be set on them, even the FullTrust assemblies that are granted all unrestricted permissions, cannot successfully pass the SNI permission demanded by your code (in .NET 1.x).
With that in place, a reasonable assumption that a .NET CAS security based app design will make about its fully secure code access, holds true – i.e. just because a calling assembly is a FullTrust assembly, it cannot pass/skip the SNIP permission that your code demands (when it was not signed with the public key that the called code is signed with), and will fail to access your secure code if it is not signed with the same public key as yours.
But CAVEAT! That assumption won’t hold good in .NET 2.0 security.
In .NET 2.0 CAS, the Identity permission classes ALLOW code to set the Unrestricted state value – i.e. PermissionState.Unrestricted.
The impact of this change in .NET 2.0 security is that if you migrate your .NET 1.1 code to 2.0 or later, your highly privileged code won’t be protected anymore by the StrongNameIdentityPermission, from any abuses by any FullTrust assemblies.
In .NET 2.0 CAS, FullTrust code can call your SNIP secured code, without having to meet the demands of the IP – i.e. any FullTrust code that is not signed with the public key that your secure code requires, can still call on your secured code.
Result: Your .NET 1.1. CAS SNIP protected code is not protected anymore when run in .NET 2.0 CAS context.
Review you CAS protected code thoroughly! If you see something like this:
public class BusinessObjectClass
{
[StrongNameIdentityPermissionAttribute(SecurityAction.Demand [or LinkDemand], PublicKey="<the key bytes">")]
public void YourCASProtectedMethod()
{ /* Your privileged code... */ ... }
}
... then its time to take action (if migrating to .NET 2.0).
Oops!! Hell breaks loose? Well…. Yes!
So, when migrating the code base to .NET 2.0, ensure to change your CAS dependant design on securing your code by either of these:
- Just don’t expect StrongNameIdentityPermission (SNIP) to secure your privileged code, and attempt alternative CAS or other security strategy, OR
- Use the application configuration setup route, and direct the runtime to use the legacy CAS .NET security policy behavior (1.x) for Identity permissions.
You could do this by using the legacyV1CASPolicy element, and set its enabled value to true.
I have some more neat strategies in mind, to sort out this .NET security issue vis-à-vis migrating code to .NET 2.0. I will blog more about those later. Watch this space.
In one of my .NET consulting projects, I am advising my customer on this exact .NET security issue :-)… so thought you all will also benefit from this bit of advice!
Next, I will blog about some precautions you will need to take when working with CAS in .NET 2.0 (vis-a-vis your .NET 1.1 code base migrated to .NET 2.0) when invoking delegates of methods (in another assembly) that are protected by CAS security demand.
The key thing here to be careful about is that there are additional checks made by CAS 2.0+ on the delegate invoker's .NET security related assembly identity bits, which you will need to be aware of so that you can have your .NET 1.1 code updated for .NET 2.0, to take into account and provide for these additional checks.
Although your current code for .NET 1.1 will work fine as-is after migrating, if the above specific aspect of CAS 2.0's additional security checks is not taken care of, then the runtime will throw security exceptions. So CAVEAT!
- Sundar