programming4us
programming4us
SECURITY

Programmatic Security (part 1) - The Permission Classes

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
1/11/2011 11:36:06 AM
Although for the most part administrative security configuration is sufficient, .NET also provides various programmatic ways to control and enforce security. You can use these powerful techniques to tighten security, optimize performance, handle unknown security policies, and deal with questionable components. In addition, programmatic security can configure security at the component level (unlike administrative security configuration, which is only as granular as a single assembly). All the permission types have corresponding classes and attributes available to you. In fact, administrative configuration uses these classes indirectly; the security configuration files are just a list of classes to use when providing the configurable permissions.

Although system administrators can grant assemblies permissions by using administrative configuration, there is no programmatic way to grant permissions. The reason is clear: if that were possible, a rogue assembly could grant itself permissions and go about causing harm. Programmatic security can deny security permissions or demand that some permission be granted. You can use the permission classes dynamically during runtime or apply them as class or assembly attributes, indicating which security action to take and when.

1. The Permission Classes

Most permission classes are defined in the System.Security.Permissions namespace, but some are spread all over the .NET Framework. All permission classes implement a set of interfaces, including IPermission, which is defined as:

    public interface IPermission : ISecurityEncodable
{
IPermission Copy( );
void Demand( );
IPermission Intersect(IPermission target);
bool IsSubsetOf(IPermission target);
IPermission Union(IPermission target);
}

IPermission is defined in the System.Security namespace. The base interface ISecurityEncodable, used mostly when constructing and persisting custom permissions, provides methods to convert the permissions to and from XML security elements.

1.1. Permission demand

The most useful method of IPermission is Demand( ), which triggers a stack walk demanding the permission of all the callers up the stack. For example, here is the code required to trigger a stack walk; it verifies that all the callers up the stack have permission to write to the C:\Temp directory:

    IPermission permission;
string path = @"C:\Temp\";
permission = new FileIOPermission(FileIOPermissionAccess.Write,path);
permission.Demand( ); //Trigger stack walk

If during the stack walk .NET discovers a caller coming from an assembly without the demanded permission, it aborts the stack walk, and the call to Demand( ) throws an exception of type SecurityException.

Using Demand( ) is how the various .NET application frameworks classes require that whoever calls them have the required security permissions. For example, the file I/O class FileStream demands permission to perform the appropriate operations (such as opening or creating files) in its constructors. You can take advantage of Demand( ) to tighten security and optimize performance as well.

For example, demanding permissions is recommended when a component uses a resource on behalf of a client. Consider the StreamWriter class. It demands file I/O permission when it's constructed with a path parameter, but subsequent calls on its methods cause no demands. The reason the designer of the StreamWriter class decided not to demand the file I/O permission in every call is because it would have rendered the class useless for performing intense file I/O operations. For example, if the client writes the entire Encyclopedia Britannica to the disk one character at a time in a tight loop, demanding the permission every time would kill the application. Not demanding the permission may be fine if a component creates a StreamWriter object and never uses it on behalf of external clients, even indirectly. But in reality, the reason a component creates a resource is to use it to service its clients. Thus, if the permission is demanded only when a component is constructed, a malicious and untrusted client could simply wait for a trusted client to successfully create the component and its resources, and then call its resource-accessing methods.

Unlike the designer of the StreamWriter class, however, you are intimately aware of the particular context in which the StreamWriter class is used. If the file I/O operations performed are not extreme, the component can compensate by explicitly demanding the appropriate permissions, as shown in Example 1.

Example 1. Protecting a resource by demanding access permission
using System.IO;
using System.Security;
using System.Security.Permissions;
 
public class MyClass
{
StreamWriter m_Stream;
string m_FileName = @"C:\Temp\MyFile.txt";
public MyClass( )
{
//The StreamWriter demands permissions here only:
m_Stream = new StreamWriter(m_FileName);
}
public void Save(string text)
{
//Must demand permission here:
IPermission permission;
permission = new FileIOPermission(FileIOPermissionAccess.Write,m_FileName);
permission.Demand( );
m_Stream.WriteLine(text);
}
}

Another example is an object that is about to perform a lengthy, intensive calculation and then save it to the disk. Ultimately, if the callers up the stack don't have the required permission, the file I/O classes throw an exception when trying to open the file. Instead of wasting time and resources performing a calculation that can't eventually be saved, the object can first demand the permission and then proceed with the calculation only if it's certain it can persist the results. Example 2 demonstrates this technique.

Example 2. Optimizing by demanding permission before performing the operation
class MyClass
{
public void Calclulate(string resultsFileName)
{
IPermission permission;
permission = new FileIOPermission(FileIOPermissionAccess.Write,
resultsFileName);
try
{
permission.Demand( );
}
catch(SecurityException exception)
{
string message = exception.Message;
message += ": Caller does not have permission to save results";
MessageBox.Show(message);
return;
}
// Perform calculation here and save results
DoWork( );
SaveResults(resultsFileName);
}
//Helper methods:
void DoWork( )
{...}
void SaveResults(string resultsFileName)
{...}
}



Note that calling Demand( ) verifies only that the callers up the call chain have the requested security permission. If the object calling Demand( ) itself doesn't have permission, when it tries to access the resource or perform the operation, the resource (or operation) may still throw a security exception.

1.2. Permission interactions

Some permissions imply other permissions. For example, file I/O access permission to a folder implies access permission to individual files in the same folder. The IPermission interface provides a number of methods that examine how two different permissions relate to each other. The IsSubsetOf( ) method returns true if a specified permission is a subset of the current permission object:

    IPermission  permission1;
IPermission permission2;
string path1 = @"C:\temp\";
string path2 = @"C:\temp\MyFile.txt";
 
permission1 = new FileIOPermission(FileIOPermissionAccess.AllAccess,path1);
permission2 = new FileIOPermission(FileIOPermissionAccess.Write,path2);
 
Debug.Assert(permission2.IsSubsetOf(permission1));



The Intersect( ) method of IPermission returns a new permission object that is the intersection of the original permission object and the specified permission object, and the Union( ) method returns a new permission object equivalent to the union of the two. .NET uses these methods when calculating the union of permissions granted by the evaluated code groups in a policy and when calculating the intersection of the policies.

: Custom Permission

In the rare case of components using a resource type (such as a hardware item) not protected by any of the built-in permissions, you can provide custom permission classes. The custom permission typically grants access to the resource only, instead of to a communication mechanism (such as a communication port or the filesystem) that can access other resources. All .NET permission classes derive from the abstract class CodeAccessPermission, which provides the implementation of the stack walk. You can start creating a custom permission by deriving from CodeAccessPermission. Custom permission classes can be used both programmatically and administratively (via custom XML representation). The assembly containing the custom permissions must be strongly named and deployed in the GAC. In addition, it must be granted full trust, and .NET must be aware of it. To register the assembly with .NET, use the .NET Configuration tool. Each policy has a folder called Policy Assemblies. Select Add from the folder's context menu, then select the custom permission assembly from the list of assemblies in the GAC. Note that you must deploy the custom permission assembly and register it on every machine that has applications using it.

Other  
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Video Sports
programming4us programming4us
programming4us
 
 
programming4us