Why would a .net web app need to check if the public key of the name of the CALLING assembly has the same length as the EXECUTING assembly's?

StackOverflow https://stackoverflow.com/questions/17937278

Question

An old .NET web app I inherited is littered with an odd "assembly security check": it checks that the public key of the name of the calling assembly has the same length as the public key of the name of the executing assembly.

The calls look like this:

CheckAssembly(System.Reflection.Assembly.GetCallingAssembly(), System.Reflection.Assembly.GetExecutingAssembly(), this);

...and that method is:

public static void CheckAssembly(Assembly callingAssembly, Assembly executingAssembly, object useObject)
    {
        byte[] assemblyPublicKey = executingAssembly.GetName().GetPublicKey();
        byte[] callingPublicKey = callingAssembly.GetName().GetPublicKey();
        if (callingPublicKey == null || assemblyPublicKey.Length != callingPublicKey.Length)
        {
            throw new SecurityException("The calling assembly does not have permission to use objects of type '" + useObject.GetType().FullName + "'");
        }
        for (int i = 0; i < assemblyPublicKey.Length; i++)
        {
            if (assemblyPublicKey[i] != callingPublicKey[i])
            {
                throw new SecurityException("The calling assembly does not have permission to use objects of type '" + useObject.GetType().FullName + "'");
            }
        }
    }
  1. I think it's checking if it's assemblies (DLL files) have not been swapped or modified or anything. Is that correct? If not, what is this code doing? Any guesses as to why it would have been written?

  2. I thought the .net framework would do this anyway, if it's needed. Right?

  3. Maybe this is old code from when the app was a winforms app and not a web app? Since it's a web app, we have complete control over what DLLs are on the server, so no security risk, correct?

(Can provide further info if needed).

Was it helpful?

Solution

Your three assumptions are probably correct, although #2 has a bit of an odd history that might be relevant here. There is a .NET Framework CAS permission, StrongNameIdentityPermission, that could be used to check for this sort of thing back in the .NET 1.x days. However, in .NET 2.0, fully trusted code started passing all identity permission checks, including for StrongNameIdentityPermission (http://blogs.msdn.com/b/eugene_bobukh/archive/2005/05/06/415217.aspx).

Before this behaviour change, a link demand for StrongNameIdentityPermission was one mechanism that folks used for creating semi-public APIs. The main disadvantage to this was that the types and members being "protected" had public visibility, and the verification only happened at runtime. This meant that a well-meaning user of a library containing such code wouldn't have any way to know that they were breaking intended usage rules until actually executing their code, which was pretty annoying. Since .NET 2.0, the preferred mechanism for creating a semi-public API is use of InternalsVisibleToAttribute to declare "friend assemblies".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top