Advertisment

On Demand Security with CAS

author-image
PCQ Bureau
New Update

Last month, we introduced CAS (Code Access Security) and saw how it could be leveraged to build applications that can be secure at runtime-from a code identification and verification perspective. This month, we will take a closer look at CAS and see how it can be used to demand specific kind of permissions for your code, before your code is actually executed by its caller. 

Advertisment

Demanding security



When working with CAS, your code can demand the CLR for a specific set of permissions to be present with the caller of your code before it code can be executed. This is particularly used when the code requires a specific set of permissions and you want all the others in the call stack to have the same. Depending upon how secure you want the demand to be, you ask the CLR to check all the callers in the call stack for the expected permission, or just the immediate caller.

Let's understand this a little better.

In this screen shot, we have a typical execution call stack. Assembly A1 invokes a method in assembly A2, which in turn invokes a method in assembly A3, which invokes a method in assembly A4. As you can see, the call stack is growing downwards. At the same time, each assembly is associated with its respective code group (G1, G2, G3, G4), which has a specific permission set applicable to it, except for the last assembly which demands a permission, P. 

Direct Hit!
Applies

to:
.NET developers
USP: Granular resource access control by code, outside the logged on security context
Links:

http://msdn.microsoft.com/library/en-us/cpguide/html/cpconCodeAccessSecurity.asp 
Advertisment

Since the assembly A4 demanded a specific permission, the CLR goes up the call stack to see if each of the callers have the permission that A4 demanded. Point to be noted here is that since a Demand was placed, all the callers in the call stack are evaluated for the demanded permission. If all of them have the permission, the code execution proceeds normally. However, if even one of them doesn't have the permission being demanded, the CLR will throw a

System.SecurityException and code execution stops.

Demanding a security level this way is the best way to ensure everyone is having the rights to do what they want to. However, since the CLR has to examine every caller in the call stack, it is a rather expensive operation in terms of execution performance, as it takes time. So, don't do a demand for every security check-there are lighter ways to check the security without compromising on the performance. We will talk about them later in this article.

Demand in action



Accompanying this article is the VS.NET 2003 source code that exemplifies security permissions being demanded. We illustrate the call stack by having method Main invoke method CallMid, which invokes method CallMid2, which in turn invokes method CallActual. CallActual will demand Write permission to the C:\ folder. To demand this permission, we create an object of FileIOPermission class, which resides under System.Security.Permissions namespace, and then invoke the Demand method against it, as shown in the snippet below :

Advertisment

Code execution call stack with permissions applied at each level of call stack

FileIOPermission refPerm = new

FileIOPermission(FileIOPermissionAccess.Write,"C:\\");



refPerm.Demand();

This way of creating permission object at runtime and demanding permission is called Imperative Security. When the Demand method is invoked, the CLR will go up the call stack

Advertisment

Main->CallMid->CallMid2->CallActual

and see if all the callers have the permission. By default, they all have the permission (unless the runtime security policy affects the assembly) and code execution goes normally. Now let's simulate a condition where one of the callers does not have the permission. We will make method CallMid not have Write permission to folder C:\ by setting a security attribute as shown below:





private void CallMid()


{ CallMid2(); }

Advertisment

This way of specifying security is known as Declarative Security. Now, when the execution takes place and CallActual demands the Write permission to the folder C:\, a SecurityException is thrown since one of the members (CallMid) in the call stack did not have permission. The screenshot shows the output.

More demands



As discussed earlier, Demand is performance intensive since the runtime has to evaluate the entire call stack for the permission in question. In case you don't want to go through the entire length and just want to ensure that the immediate caller has the requested permissions, use LinkDemand as shown below:





private void CallActual()


{


FileIOPermission refPerm = new FileIOPermission(FileIOPer missionAccess.Write,"C:\\");


refPerm.Demand();


StreamWriter writer = new StreamWriter("C:\\CASDemo.txt");


onsole.WriteLine("Hello World");


writer.Close();


Console.WriteLine("\nPress Enter to continue...");


Console.ReadLine();


}








Advertisment

A SecurityException is thrown when permission demand fails

LinkDemand takes place at JIT and the runtime evaluates only the immediate caller for the permission being demanded. Thus, in this respect, its weaker than the Demand methodology, but doesn't incur as much performance load as Demand. 

Conclusion



CAS is a very powerful tool that helps you build better and more secure design applications. Next month, we will look at Isolated Storage, understand it and see how it can be leveraged by your applications-particularly smart clients.

Kumar Gaurav Khanna

Advertisment