Limiting Callers to a .NET Assembly

Limiting Callers to a .NET Assembly

  • Comments 12

I've been asked the same question several times over the last couple of months, which suggests that possibly the answer isn't as well known as I presumed. Since I have to remind myself of the specifics of the answer each time, I figured I'd post both question and answer to save us all time in the long run!

Q. How can I limit access to a .NET assembly that I've created? I've got two separate assemblies A and B. A references B and uses a number of instance methods on B, but I don't want any other assembly to be able to access B. In effect, I'd like to make B "private" to my application. Is there any way to achieve that with .NET?

A. There are probably a number of ways to achieve this, but the simplest involves signing your calling assembly A with a unique public / private key pair (use sn -k to achieve this). Once it's signed, you can use the StrongNameIdentityPermission attribute on the callee assembly B to demand that any callers are signed with a matching public key. If any other assembly tries to call B that isn't signed with the same key, a SecurityException will be thrown.

For more information on the StrongNameIdentityPermission attribute, see the appropriate topic in the MSDN Library. There's also a good walkthrough here.

  • Couple of other recommended resources as well - from the PAG "Improving Web Application Security" Tome. Chapter 8 – Code Access Security in Practice http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh08.asp Chapter 9 – Using Code Access Security with ASP .NET http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh09.asp
  • Problem is... you can remove a signature from an assembly with ilasm/ildasm very easily. After that you can remove the attribute from the assembly in ilasm, and you're set. sn.exe also has a parameter '-Vr', which makes an assembly be skipped for signature checking. All in all, signing your code is not the way to protect it. I did it this way with my product, but a hacker showed me how to do remove this 'protection' in 30 seconds.
  • Thanks Frans. I wasn't really thinking of this technique as a mechanism for code protection or obfuscation; apologies if that's how the entry comes across. There are ways to prevent what you describe, but if you're relying on this alone to prevent malicious attempts to access the code, I agree that you'd come unstuck fairly quickly. This does prevent inadvertent usage of an assembly which is intended for private use within an application, however. Thinking of the service-oriented architecture model that people are increasingly working with, it's important to design in clear service boundaries within an application and prevent people undermining these contracts by calling into other assemblies. Using a technique such as the one I describe above can help enforce that. At the end of the day, it's all about making things more difficult rather than preventing them altogether. Even if you mark a class method as "private", you can access it using reflection, after all. Thanks for the comment - the point you made is an important one. Tim
  • The only shortcoming of this technique, if I'm not mistaken, is that you have to apply that attribute demand to every class or method within the assembly. You cannot apply that attribute to the assembly as a whole. I remember reading somewhere that .NET 2.0 will fix this, however.
  • Paul, If you go to the MSDN documentation, you'll see that this attribute can be applied at the assembly level as: [assembly:StrongNameIdentityPermission(SecurityAction, StrongName)] Is that what you were looking for? Tim
  • Hi Tim, Thanks for the pointer to the documentation. I did try to apply the attribute at the assembly level, but I get a build error when I try to compile: vbc : error BC30145: Unable to emit assembly: SecurityAction type invalid on assembly. -or- error CS1577: Assembly generation failed -- SecurityAction type invalid on assembly. with the following attribute declaration in assemblyinfo.vb: <Assembly: StrongNameIdentityPermission(SecurityAction.LinkDemand, PublicKey:="....")> This occurs with VS.NET 2002 & 2003, in C# and in VB.NET, as well as the PDC build of Whidbey. If, however, I apply the same attribute at the class level, it works: <StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey:="...")> Any suggestions? Thanks!
  • The documentation for SecurityAction explains which ones are allowed at assembly level. http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemsecuritypermissionssecurityactionclasstopic.asp
  • Hi, with regard to the point made by Frans Bouma. Tim replied saying that there were other means to better protect assemblies for code protection and obfuscation. Could anyone elaborate on what these methods are? Thanks..Tom
  • PingBack from http://therning.org/magnus/archives/41
Page 1 of 1 (12 items)