Saturday, October 23, 2010

.NET 4 Assembly Security's Fresh-New DLL Hell

If you've been installing applications that use the .net 4.0 framework you probably have seen this message:
Problem signature:

Problem Event Name: CLR20r3
Problem Signature 01: cps.fuzzypreproc.exe
Problem Signature 04: Cps.FuzzyPreProc
Problem Signature 09: System.IO.FileNotFoundException
OS Version: 6.0.6002.

If you're like me, you first checked to see if all your assemblies were copied locally and that your .exe permissions were appropriately set.  When you discovered that all these things were in order you probably started searching the net only to find millions of hits describing how this error has plagued developers in every form or .net for different reasons over the years.  Basically your Google results are a misleading spam of old problems and solutions.

If you have this problem AND are building with Visual Studio 2010 in .Net 4.0 you will experience this error for a different reason than all the other generations past that have suffered with it.  (The security requirements of .net 4.0)  .Net 2.0 used to use something called security "transparency" which allowed the .net 2.0 clr to find a matching dll and load it no matter if it was in the GAC or not.  No doubt this was done to ease the pain of .net developers competing against fast and loose java deployments which require little more than pushing a cleverly disguised .zip file to the server.  Now that security is being built into VS2010 more seriously we find that strongly named assemblies need a little more care. 

Specifically if you have a strongly named assembly and are design-time binding it. Reffing it directly in the designer you will be forced to install it into the GAC.  This means that your installer must be run locally on the server and the assemblies will be loaded into the GAC as trusted assemblies with appropriate permissions.  But your app will no longer find assemblies in it's local directory just by virtue of being there.  This new change is designed to resist hacking by keeping a malicious software developer from dropping a strongly named assembly in the local directory of an application and have it get picked up by the exe when it runs next.  Even though this would likely require a trusted access to a server (maybe even admin access) Microsoft is trying to lock down the deployment environment against tech savvy attackers.

If you have seen this bug, chances are it's been with a frequently updating tool set like a Telerik or some similar GUI tool set that tries to keep up to date with the latest compilers.  The problem does not seem to affect assemblies built with former versions of .net even if they are used under .Net 4.0. 

So what do you do to fix this problem?  Microsoft suggests that you can use the solution in the post below, allowing for apps to use CLR 2.0 conventions if necessary, or you can run the client install of your tool set on the server (... i know... probably forcing you to fork out more dollars to the vendors and causing you more licensing problems) or you can build your own installer and digitally sign it.  A common suggestion is configuring a click-once install but there are permissions problems with it if installed remotely and you still have the problem of getting your assemblies into the GAC.  So I'd recommend the 2.0 support only if other solutions are impractical.  You may want to run as administrator and open Explorer to c:\Windows\Assembly\ and drag your files into the GAC.  But good form probably dictates having a signed install if you're going to be doing this regularly.  But once the strongly named assemblies are in the GAC this problem will magically disappear.