Trusting Applications with their Strong Name

Last time I talked about reasons that you might want to strongly name your application's entry point.  The most obvious reason is so that you can setup your security policy to increase the level of trust given to that assembly by the default policy.  You would do this by signing the entry point exe, and other assemblies that make up the application, and then using the StrongNameMembershipCondition to create a code group that provided the trust level you wanted for the application.

However, determining where to place that code group is not as obvious at first glance.  Most likely, you'll want to add the code group as a child of the zone that you expect the application to be run from.  For instance, if you have a key that your IT department signs applications with, you might want to trust this key.  Doing this enables you to run their applications directly off of their shares, without needing to copy locally to avoid SecurityExceptions.  You would want to make the code group a child of the LocalIntranet code group:

Location of a StrongName code group trusting an IT department's public key

Why place the group here?  Lets say I added a code group trusting a key that I know some useful internal application uses.  Now, lets say that some malicious person on the Internet were to somehow get a hold of the private key.  If I placed the code group trusting the key as a child of my root code group, this malicious user can now create assemblies that I treat as FullTrust.  Now, if they can get me to browse to their website, they can do whatever they want to my machine or with the data on my machine without me even knowing it.

The problem gets more widespread the more common the code group is.  For instance, every default install of the .NET Framework contains a code group that gives anything signed with the Microsoft public key FullTrust.  That makes being able to sign with this key a juicy target for attackers.  However, since the code group is a child of MyComputer, not only would they have to break the Microsoft key, they'd also have to find a way to get the assembly onto your machine, and get you to run that assembly.  That's a lot more work than getting me to browse to a web page, which would be all that is necessary if the Microsoft group was a child of AllCode.

Basically, this is defense in depth.  I know that I'm trusting assemblies signed with a specific key so that I can run code from that author from a specific location.  Code coming from a different location should fail by default, unless I decide to explicitly trust it.  In fact, on my personal machine I go a step farther than just adding the code group as a child of LocalIntranet.  I generally create children of LocalIntranet which use the UrlMembershipCondition to match the specific sites that I want to trust.  Those code groups grant Nothing, but have children code groups that match specific public keys.  In this way, I logically and a set of three conditions together in order to recieve elevated trust.

  1. The assembly must be on my local intranet
  2. The assembly must be on a specific URL
  3. The assembly must be signed with a specific key.

If any of those aren't met, then the assembly defaults back to LocalIntranet permissions.