views:

269

answers:

3

In .NET 1.x, you could use the StrongNameIdentityPermissionAttribute on your assembly to ensure that only code signed by you could access your assembly. According to the MSDN documentation,

In the .NET Framework version 2.0 and later, demands for identity permissions are ineffective if the calling assembly has full trust.

This means that any application with full trust can just bypass my security demands. How can I prevent unauthorized code from accessing my assembly in .NET 2.0?

+1  A: 

See this article:
http://blogs.msdn.com/ericlippert/archive/2008/10/06/preventing-third-party-derivation-part-two.aspx

Particularly this part:

In recent versions of .NET, "full trust means full trust". That is, fully-trusted code satisfies all demands, including demands for things like "was signed with this key", whether it actually was signed or not.

Isn't that a deadly flaw in the security system? No. Fully trusted code always had the ability to do that, because fully trusted code has the ability to control the evidence associated with a given assembly. If you can control the evidence,then you can forge an assembly that looks like it came from Microsoft, no problem. (And if you already have malicious full-trust code in your process then you have already lost -- it doesn't need to impersonate Microsoft-signed assemblies; it already has the power to do whatever the user can do.)

Apparently, the .Net designers felt that this attribute wasn't very effective for full trust code in .Net 1.x either.

Joel Coehoorn
Joel - the question remains, how do you prevent unauthorized access?
Jon B
That is true. I posted this to show that the question is based on a false premise: the method he was using didn't really work in 1.x. There's a brief exchange in the comments of that article, where Eric Lippert's response to the question is basically "use a lawyer".
Joel Coehoorn
A: 

As Joel indicated, you are out of luck with regard to CAS. However, you may be able to do the check yourself in any method you need to protect by using Assembly.GetCallingAssembly() to get a reference to the assembly containing the calling code, then check the strong name on that assembly manually.

Eric Rosenberger
This is what I am doing. I was hoping of finding a better way. This throws an exception at runtime. I would prefer to catch the error or at least a warning at compile time.
Rob Prouse
+2  A: 

As per Eric's suggestion, I solved it by checking the key myself. In the code I want to protect, I add the following call,

EnsureAssemblyIsSignedByMyCompany( Assembly.GetCallingAssembly() );

Then the implementation of that method is

  /// <summary>
  /// Ensures that the given assembly is signed by My Company or Microsoft.
  /// </summary>
  /// <param name="assembly"></param>
  private static void EnsureAssemblyIsSignedByMyCompany( Assembly assembly )
  {
     if ( assembly == null )
        throw new ArgumentNullException( "assembly" );

     byte[] pubkey = assembly.GetName().GetPublicKeyToken();
     if ( pubkey.Length == 0 )
        throw new ArgumentException( "No public key token in assembly." );

     StringBuilder builder = new StringBuilder();
     foreach ( byte b in pubkey )
     {
        builder.AppendFormat( "{0:x2}", b );
     }
     string pkString = builder.ToString();
     if ( pkString != "b77a5c561934e089" /* Microsoft */ &&
          pkString != "abababababababab" /* Ivara */ )
     {
        throw new ArgumentException( "Assembly is not signed by My Company or Microsoft. You do not have permission to call this code." );
     }
  }

** Names and keys changed to protect the innocent. Any likeness to real names or companies is merely a coincidence.*

Rob Prouse
You should use GetName().GetPublicKey(), not GetName().GetPublicKeyToken() to verify if assembly is signed by parties you trust. Token is just a short representation of a full key.
Juozas Kontvainis
However even that will be ineffective against someone determined - because "fully trusted code has the ability to control the evidence associated with a given assembly. If you can control the evidence,then you can forge an assembly that looks like it came from Microsoft, no problem" ( http://blogs.msdn.com/ericlippert/archive/2008/10/06/preventing-third-party-derivation-part-two.aspx )
Juozas Kontvainis