Introduction to Security
Introduction to Security
Security is very hot topic these days. Each new virus takes advantage of a different flaw in the OS or in an application. The .NET Framework adds several new tools to help the application developer create a "secure" application. These tools can be classified as role-based security, code-based security, and runtime security.
Role-based security is closer to the traditional security infrastructure. Each user is assigned a role and that role has certain privileges and restrictions. The logged on user is known as a Windows principal. There are two classes within the .NET Framework that encapsulate the identity of a logged on user, WindowsPrincipal and WindowsIdentity. The WindowsPrincipal class has an 'IsInRole' method to determine if a particular principal is a member of the specified role. Using the 'AuthenticationType' method makes it possible to check the authentication that was involved with principal. Because some authentication schemes are stronger than others you might want to assign a stronger trust based on the authentication. It is also possible to express the identity of a user in a generic fashion using GenericPrincipal and GenericIdentity. Similar to WindowsPrincipal you can test for role membership using the 'IsInRole' member of the GenericPrincipal class. A role-based security permission is formed using the PrincipalPermission class. An instance of the PrincipalPermission class is constructed using the principal name and the role. If you require a set of principals and roles there are methods in the PrincipalPermission class that allow you to combine instances of the PrincipalPermission class is various ways. When the conglomerate PrincipalPermission object is formed the 'Demand' method can be called at runtime to determine whether the current principal matches the permission specified. If the 'Demand' succeeds, the execution path continues on to the next statement. If the 'Demand' fails, a SecurityException is thrown, which the application catches and handles appropriately.
Code-based security is a new concept with the .NET Framework. This model assigns security attributes to the code, not who is running the code. In other words, if the code is denied access to a particular security privilege it does not matter who is running the code, access will always be denied. All code-based security is handled from the base class CodeAccessPermission. Unlike PrincipalPermission, CodeAccessPermission can and is inherited by a number of permission classes in the base class library of the .NET Framework. Below is a list of the documented derived classes from CodeAccessPermission:
DBDataPermission PrintingPermission MessageQueuePermission DnsPermission SocketPermission WebPermission EnvironmentPermission FileDialogPermission FileIOPermission IsolatedStoragePermission PublisherIdentityPermission ReflectionPermission RegistryPermission ResourcePermissionBase SecurityPermission SiteIdentityPermission StronNameIdentityPermission UIPermission UrlIdentityPermission ZoneIdentityPermission
Each of these classes is constructed and has methods specifically targeted for the particular permission. This is similar to how FileIOPermission has specific methods for specifying the file path and the kind of permission desired. When the permission is formed then subsequent access using managed code results in the appropriate permission check. Again using the FileIOPermission class, if permission was only allowed for file A yet the code bypassed the File class to do unmanaged access to file B, there would be no security check because the unmanaged code is not aware of the managed code permission settings. The managed code permissions are independent and distinct from the permission granted through the OS (say through ACL lists).
Finally, runtime security is is inherent in the .NET Framework and the CLR itself. Type safety is a key design goal for any language that complies with the Common Language Specification and is supported by the CLR. Unlike C and C++ casting is very tightly controlled when an application is running under the CLR. Many applications can be declared "verifiably type safe." A type safe application will operate only within the bounds set by the program. One of the key virus exploits is a buffer overrun. In other words, a virus gains access to the stack or the execution of a program because it takes advantage of a forced or unforced error in handling access of data outside the bounds of an array or program. A buffer overrun would be something as simple as the access of the third element in an array that has allocated space for only two elements, or accessing a character variable as if it were a larger integer or floating-point value.