|
Code access Security is a new concept brought in by the .NET framework. Code access security essentially involves granting permissions to an assembly. Code access security uses the location of assembly and other information about the identity of code as a primary factor in determining permissions to be granted to the assembly. This information about the identity of an assembly is called
evidence. Once loaded in runtime, the code starts executing in the restricted environment depending upon permissions granted to it. If the code is not trusted enough to run or runs but performs an action for which it has no permissions, then a security exception is thrown. The code access security system means we can stop running of malicious code and also restrict the code to run in a restricted environment where we are sure that it won’t do any damage to the resources. Let us now see few cases where code access security becomes crucial.
Suppose an organization is working with some extremely important data, we would use code access security system to state which code is allowed to access the database and which is not. Similarly if we run an application from a network drive and it tries to access the file on a local drive an exception must be thrown. This can be done using code access security system.
It is important to know that code access security protects resources like local disk, network, user interface from malicious code. It is not a tool for protecting
software from users.
Code access security works on the basis of Code Groups and Permissions.
Code Group
Code groups are a grouping of assemblies with same privileges. For example, code groups include “Internet” and “Intranet”. The group Internet includes code downloaded from Internet and the group Intranet includes code sourced from LAN. The information based on which the assemblies are grouped is called
evidence. The assembly loader is responsible for collecting the evidence at load time based on where the code is loaded from. The CLR ships with seven types of evidence.
- Zone: Region from which the code originated
- Site: Web site from which the code was downloaded
- URL: Specific location of the code
- Application Directory: Location of the assembly
- Strong name: The unique name for the code
- Publisher: Publisher of the code
- Hash value: Hash value for the assembly
Collectively these seven types of evidence are called host evidence as they are implemented by the host environment.
Permission
Permission means authorization to perform actions. These actions often involve accessing certain resources. These permissions are exposed programmatically through the
System.Security.PermissionSet namespace.
Whenever a code is running, the CLR has to decide which permissions to grant that code and which ones to deny. The CLR decides which permissions to grant and which to deny by doing a simple trick, it checks whether the caller of our code has the permission perm1 or not. CLR repeats this process for the callers of our assembly till there are no more callers are left. If all the callers have that permission, our code is granted the requested permission. This can be better explained by the following example.
Consider an assembly A. which calls Assembly B, B in turn calls C. C finally calls our assembly D. If our assembly demands a certain permission say perm1, the CLR will first check whether our
assembly's caller (C in this case) has that permission. If it has, the CLR further looks whether B has it or not. If B has that permission, the CLR finally checks to see whether the root assembly A has the demanded permission. If all of the preceding assemblies C, B and A have that permission, our assembly is also granted the permission.
Even if any one intermediate assembly does not have the demanded permission, our assembly is denied perm1. This process of checking permissions of all the parent assemblies is known as Stack Walking. Stack Walking is a costly activity, but considering the gains it has to offer in terms of security implementation, Microsoft decided to implement it in the CLR.
Assemblies demand permissions when it is clear that without those permissions the assembly will not execute. Demanding permissions is done programmatically. The following program shows us how.
Our program will read a file from the local disk and display the first line. In our program we will demand complete access to the ‘C:\’ drive. If the access demand is denied, an exception will be raised which we will catch.
Create a Windows based application and design the form as shown below.

Name the text box as t, Read button as
bread and Exit button as bexit. Add the following code in the constructor of the
Form1 class just below the call to InitializeComponent( ) method.
FileIOPermission fp ;
try
{
fp = new FileIOPermission( FileIOPermissionAccess.AllAccess, @"C:\" );
fp.Demand( ) ;
}
catch ( Exception e1 )
{
MessageBox.Show ( e1.Message ) ;
}
Here we create a reference of type FileIOPermission. We have inisialised the reference in the
try block. In the constructor we have passed the AllAccess enumerated type to specify that our code needs complete access permissions to the ‘C:\’ drive of the machine where our application is to execute. The constructor is followed by a demand for the above permission.
It is necessary to place the demand part in a try-catch block because if the permission is denied, the
Demand( ) method would raise an exception and our program would be terminated abruptly.
Now add a handler for the Read button. Write the code as shown below to it.
private void bread_Click ( object sender, EventArgs e )
{
StreamReader sr = new StreamReader ( "c:\\hi.txt" ) ;
t.Text = sr.ReadLine( ) ;
sr.Close( ) ;
}
We have created a stream reader object to read the “c:\hi.txt” file. Next we have read a line from that file and displayed it in the text box
t.
Now add a handler for the Exit button and call Dispose( ) method from it. Calling
Dispose( ) would terminate the application if the Exit button is clicked.
Finally add the following declarations at the beginning of the program.
using System.IO ;
using System.Security ;
using System.Security.Permissions ;
Run this application in various scenarios, like on the local machine with security on, local machine with security off, copy it to another machine and run it from the remote computer. Configure security policy to give full trust for code from the remote machine and run the program. Also try out running the program from the remote computer with security switched off. To switch the security on/off we can use the ‘caspol’ utility that is shipped with Visual Studio.NET. This exercise will give you a better insight into the working of code access security.
|