Securing .NET Assemblies

Introduction

We all have worked on .NET and we know there are so many security features that are available. One among them is CAS (Code Access Security). Well, I am not going to discuss what CAS is and how it works? Here, I'll try to explain how is CAS helpful in providing security to our applications?

Description

Most of us are working and developing applications on enterprise level and the architecture that we follow is n-tier. In a typical scenario, we have a UI layer, business layer and a data layer or if we talk about design patterns then we have the MVC pattern which again talks about different layers. When we work on enterprise level it becomes necessary to secure the code libraries from the outside world. This is due to certain business rules in a business layer, or in the case of data some data rules which they don’t want anyone to know. Keeping this in mind, we will implement an example of how to secure our development layers.

Let’s create an assembly, Assembly1. The code for Class1.cs is given below:

Once you are done try executing the application, well it will work without any issues. But now the question is: Are these assemblies secured? Just signing it with a strong name key doesn’t make it secure as any one can use this assembly in his application.

Let's take a second step where we use CAS - declarative approach for securing our classes. Now add the following code above your class1 code in Assembly1:

After adding the above code, try re-executing the application. The first message box is displayed but the second message box will throw a security exception to the user as the user is using a different key pair (key1.snk) to strong name Assembly2 (check the code of AssemblyInfo.cs). Now, change the Assembly2 key pair to Key.snk in assemblyinfo.cs and execute the code again. Now, everything will work the way it has to.

Let me explain what I did by adding the StrongNameIdentityPermissionAttribute: this attribute helps in protecting class' public key pair of a strong name key used which is key.snk. And whenever an assembly, say X, references it to use the methods then X should have the same key available and used in the code, otherwise he won't be able to use our assembly.

In the above code, I have specified SecurityAction.LinkDemand with a public key. LinkDemand helps in walking down the stack walk and checking each assembly's evidence. If it matches it will allow and if not it throws an exception. I would have used SecurityAction.Demand but Demand checks the evidence of the immediate caller and in the above case it’s winform.dll which doesn’t have this evidence so it's going to fail. Well, you can check this by replacing LinkDemand with Demand and executing the Win Form application.

Let’s change the above example. Take out the intermediate assembly Assembly2 and use Assembly1 in your application and on the click of a button comment the first code and add these two lines:

Now execute the code. What do you see in the result? As soon as you click the button a security exception pops up as your application doesn’t provide the right evidence. Now in the assemblyInfo.cs add the key file as:

@"..\..\..\key.snk"</CODE>

And then execute the code again. Now it will work the way it has to. Well, I think I have cleared the point of making assemblies secure.

Try creating a console application with the same assemblies and instead of LinkDemand use Demand. Check the results, it will work perfectly. The reason is when we execute a Win Form application the winform.Dll works as an intermediate between the form and the assembly which creates the problem but for the console application it’s a straight way compilation and so there is no intermediate DLL to interact with. That’s why it works perfectly.

In the end, I would like to say "Happy coding"!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

Currently i am working as a Technical Architect Microsoft .Net Practices in Sogeti USA, NY. I am one of the winner of Microsoft Architect Contest 2004. I have 8 years of experience in the IT industry. Doing R&D on new technologies and reading about them is one of my big time interests.

Comments and Discussions

You have actually secured the class only, not the entire assembly. The problem with this approach is that when adding new classes to a library that should be totally secured, there is always a chance that one forgets to prefix the new class with the attribute.Lexa S.

Hi Lexa Well if you know the way SecurityAction attribute works then you also know that its a enumeration and you can use this either at a class/method or assembly level. This example was for the class level permissioning and explaing everyone CAS and its working. But in case you want to use it at a assembly level then you can add the attributes in the assemblyinfo.cs file for e.g."[assembly : IsolatedStorageFilePermission(SecurityAction.RequestMinimum,.....]". And this way it will effect your whole assembly.

Hi Lexa, Are you trying to use .Net 1.1 or .Net 2.0? with .Net 2.0, you need to give the key file name in the project properties instead of in the "AssemblyInfo.cs" so that could be one of the reason that other assembly is not getting signed and this feature is failing. Try this out and let me know if again your are facing any problem. You can alternatively reach me at atul.malhotra@mphasis.com.

My name is Walter. I’ve made some test’s with the project that you put in your article. When I execute the project in VS 2003, this works fine, therefore the project validate the assembly correctly. When I execute in VS 2005, it doesn’t work, therefore the project doesn’t validate the assembly, anyone can call the method in assembly that is protected with the attribute StrongNameIdentityPermissionAttribute.

Thanks Harkos for your suggestion. Well the time code has been put online was my testing code and without doing any changes i just put online. It's true in any way to have the pulic key in a different class as a constant to readonly as later any changed doesnt require anyone to touch the main class. Thanks once again.