.NET Security

Visual Studio 2005/2008, "Delay signing" message text fuss.

Many people have asked about this to me, with a hesitation in their minds to delay sign their assemblies, given the message text that sits in the "Signing" tab page in Visual Studio (2005 and 2008) Project settings view.

Hence I thought I will blog my replies on this anyway, just so that it could be useful to all others out there with the same worry in mind.

When you attempt to setup partial signing, you can get confused or worried by the message that you see in the bottom of "delay signing" checkbox in Visual Studio setting page.

Delay signing

This is the message that gets people worried (at least at the first look/instance) and gets them thinking if they should skip delay signing completely.

To be frank, that message you see there, is not worth so much of importance as-is. I know what MS is trying to say there, but they have not used the correct message text to convey what they intended to say :-)

All that MS would want to convey there is that if you did delay signing, then (specifically for VS 2005) the hosting process - i.e. the <App name>.vshost.exe will attempt to block any debugging activity once the delay signing switch set to ON is detected.

This was the case at the time of VS 2005. This has been addressed now.

Also, the message is trying to say one other thing - I.e. since you will be signing only with a  part of the full key pair when delay signing our app, the crypto bytes that gets into the assembly manifest will end up being null/0 bytes - which is expected.
But when the app is run, the CLR (runtime verification process) will detect this fact and then fail to load the assembly, since the encrypted hash will be 0 bytes, it will be taken as a tampered assembly, and hence will fail the .NET security verification process, and will end up throwing a FileLoadException, and consequently won't run the assembly.

Hence the message that you see in the Signing tab in the page saying that if you delay sign it, you won't be able to debug or run the assemblies.

But it is not fully correct on the part of MS to say what it says there, with just those words in there, because it can lead you to be confused.

What actually will happen is, in the context of development builds / tests / debugging, we will (obviously) need to switch off the run-time verification process - i.e. via the sn- Vr / secpol toolset + through our local development build scripts / process, which we will do anyway, if we are building delay signed assemblies, and will be debugging it for development tests, et al.

But what Microsoft overlooked (and continues to do so) is the fact that those who delay sign the assemblies will know to switch off the verification process in their sandbox / development machines in order to be able to debug the apps, and they simply came up with that message text that you see in the Signing page in VS 2005/8 setting page :-)

Although this may sound a trivial issue, it will be good on the part of MS to fix this message text in Visual Studio. This has been around from the time of VS 2005, but it is annoying to see this not addressed even in the VS 2008 release.

MS should either change the text, so as to make the information clear, or the note should be completely removed altogether.

I would personally favour the later option, since the host (vshost.exe) does not anymore detect this setting  and disable debugging facilities (as it used to do in the early VS 2005 times), and also considering the fact that developers / teams who will be delay signing their project do know what they should prepare in order to debug/run their delay signed assemblies.

Anyway, until MS addresses this, rest assured that there is no need to get confused or alerted by that little (partially) incorrect message :-)

You can delay sign your apps, and run them, debug them et al.

Just ensure that your development build process has the scripts setup to switch off the run-time verification process.

That said, it is not advisable to simply switch off the run-time verification on all assemblies, since that can bring in security risks to your development machine.

Instead switch off the verification process only based on your delay signed assemblies's public key part token, with which you can then run a command something like this:

sn -Vr *, <your delay signed assemblies's public token part of the full secure key pair>.

- Sundar


.NET Security: CAS vis-à-vis Migrating 1.1 code base to .NET 2.0: StrongNameIdentityPermission

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