| By Thom Robbins | Article Rating: |
|
| February 24, 2003 12:00 AM EST | Reads: |
20,348 |
Remember the old days when we only installed applications that were purchased from the local computer store? Actually, this was the only way to get the application media. Also, because we had mass-produced disks or tapes this provided an additional sense of security.
Of course, there were application bugs and unexpected features, but we never expected an application would intentionally destroy a desktop or server. This model doesn't work today when most software is downloaded or application code is embedded in other formats. Everything from a simple Web page to e-mails containing scripts are downloaded and run on our local machines.
The sad truth is some of this code is malicious. All companies take the necessary precautions to protect their users and critical data from the malicious code. These include firewalls, virus checkers, and common sense. Ultimately, today it seems we are always at risk. The .NET Framework provides Code Access Security (CAS) to help solve this problem and secure our systems from malicious code. In this article, I'll show the basics of how you can use CAS and the .NET Framework to protect your system.
CAS provides a centralized mechanism to assign permission levels for individual sections of code based on their origination and identity. For example, we may want to restrict Internet-downloaded controls to only accessing the user interface and specifically deny any type of access to the local file system. However, for a small set of trusted vendors we want to provide local file system access. The problem with this example is that traditional Windows-based security doesn't provide this granular level of support. CAS, which is part of the .NET Framework or Common Language Runtime (CLR), provides the ability to set and maintain this type of system security policy.
CAS Basics
All applications that target the CLR operate in a managed environment. Among other things, this means that all code must interact with the CAS system runtime. System administrators are able to manage and uniquely specify permissions granted to each managed code assembly. Any time managed code attempts to access a protected resource (i.e., opening a file) the assigned permissions are checked. It is important to remember that the CLR walks the entire call stack when performing these checks. This prevents untrusted top-level assemblies from bypassing security checks on the lower end of the stack and gaining additional unauthorized access. The bad news is that CAS and the CLR don't have the ability to control and secure traditional unmanaged code such as COM (Component Object Model) objects. These objects deal directly with the WIN32 operating system and execute outside the control of the CLR. The good news is that CAS does offer the ability to turn unmanaged code execution on or off.
During the installation of the .NET Framework a default security policy is implemented for CAS. This policy defines the basic rules that all applications are granted by default. Actually, this is a pretty good starter set but should be thoroughly reviewed for specific concerns that companies may have. As you would expect, the policy is less restrictive for locally running applications and more restrictive for Internet-based applications. There are two ways to modify the default security framework. First is a standard MMC console (mscorefg.msc). This is the preferred method for modifying application security (see Figure 1). Second is a command-line utility called caspol.exe. This utility provides an easy to script security batch upload interface.

Assembly Requests
Essentially, Code Access Security allows each .NET assembly the ability to run with different assigned levels of privileges. Each assembly must provide specific evidence that includes its origination (Internet, intranet, or local) and optionally a public key to support its security request. CAS then evaluates these against the local security policy to determine the effective security. If at any point the assembly attempts to gain additional unauthorized permission, the CLR rejects the request and raises a security exception. One of the real benefits for end users is that they are no longer asked whether or not to trust code during application execution. Effectively, the defined security policy and assembly evidence determine the authorization level.
Developers don't have to request permissions for their code to compile and run within the managed environment of the CLR. Ideally, it is a good practice that can make end users and system administrators better able to manage your applications. Of course, the real benefit is that by requesting permissions you are increasing the chance that your code will be allowed to execute. Additionally, if you don't identify a minimum set of permissions it becomes the developer's responsibility to gracefully handle all runtime security errors. System administrators are also able to provide a base set of permissions that meet your requested applications, requirements. Administrators can use the Permission View (permview.exe) tool to examine an assembly and issue the requested permissions. If you don't provide a base permission request, administrators can't effectively determine base permissions, which can make your application difficult to administer.
Permissions are requested by applying attributes at the assembly level. These attributes vary depending on the specific permissions requested. These requests are compiled into the metadata of the assembly manifest and evaluated when code is loaded into memory for execution. Probably the most common permission request is to access unmanaged code. Listing 1 is an example of the assembly level request that uses the SecurityPermission attribute to request this access.
The SecurityPermission attribute requires two values. The first is the SecurityAction that specifies the permission requested (Request Minimum) and a flag that indicates the requested permission (SecurityPermission Flag.UnmanagedCode).
Demand-Based Security
In addition to specifying security requests within the assembly level, you can also issue a security demand with your application. This demand specifies either declaratively or imperatively the permissions level that both direct and indirect callers must have to access your application code. Typically, direct callers are defined as members that call either static or instance methods of your application library. Indirect callers on the other hand, call either static or instance methods of another library that in turn calls yours. Within a demand request, any application that includes your code will execute only if all direct and indirect callers have the necessary security.
Demands are ideal for situations where class libraries access protected resources that you don't want to provide access to untrusted code. Demands can be placed in code using either imperative or declarative syntax. Remember that most classes in the .NET Framework already have demands associated with them. So by default you don't have to make demands associated with protected resource access. For example, the Stream Writer class automatically makes a security demand for FileIOPermission whenever it is opened. An additional demand for FileOPermission every time you use the Stream Writer class causes an inefficient stack walk. As a general rule demands are best suited for unique resources that may require custom permissions.
Declarative demands place requests directly into your code's metadata using attributes. You can use declarative syntax to place a demand in either the class or method level of your code. If you place a declarative security check at the class level, it applies to each member of the class. However, if you place a declarative security check at the member level, it applies to only that member and overrides any permissions specified at the class level. For example, suppose you specify at the class level that PermissionA is required, and for that class's Method1 you indicate that PermissionB is required. When Method 1 is called, a security check will look only for PermissionB, but other methods of the class will still require PermissionA.
The following example places a declarative demand for a custom permission called CustomPermission on all callers of the ReadData method. The custom permission has a separately defined CustomPermission Attribute that makes the demand. In this case, it takes a SecurityAction.Demand flag in order to specify the type of demand the attribute will perform.
<CustomPermissionAttribute(SecurityAction.Demand, Unrestricted = True)>
Public Shared Function ReadData() As String
'Read from a custom resource.
End Function
Imperative demands are placed in the method level of your code by creating a new instance of a permission object and calling that object's Demand method. The imperative syntax cannot be used to place demands at the class level. The imperative demand that you place in your code effectively protects all the remaining code in the method in which the Demand method is called. The security check is performed when the Demand is executed; if the security check fails, a SecurityException is thrown and the rest of the code in that method or member is never executed unless the SecurityException is caught and properly handled.
The following example uses imperative syntax to place a demand on all callers for the custom permission CustomPermission. This code creates a new instance of the Custom Permission class, passing the PermissionState.- Unrestricted flag to the constructor and then calling the demand method.
Public Shared Sub ReadData()
Dim MyPermission As New CustomPermission(PermissionState.Unrestricted)
MyPermission.Demand()
'Read from a custom resource.
End Sub
Role-Based Security
Up to this point we've discussed how Code Access Security revolves around the idea of code and not around the idea of users and roles. There is always a need to define security based on user identity. The CAS runtime also provides role-based security features that have become a standard within many enterprises, especially with the adoption of Active Directory. Within role-based security, two base levels are used: Identity and Principal.
Identity represents the user on whose behalf the code is executed. Keep in mind that this is a logical representation of the user defined by the application or developer. A principal; on the other hand, represents the actual abstraction of the user and the roles that they belong to. Classes that represent a user's identity implement the Identity interface. An example of a generic class providing a default implementation of this interface within the .NET Framework is Generic Identity. Classes representing Principals implement the IPrincipal interface. An example of a generic class providing a default implementation of this interface within the .NET Framework is GenericPrincipal.
At runtime each thread has only one current principal object associated with it. Based on the specified security requirements, code may access and change this object as needed. Each Principal has only one identity object. For example, Listing 2 shows a generic implementation of role-based security.
Conclusion
This article has covered quite a bit. There are a couple of things that you should remember. First, by default the security policy gives significantly more trust to code executed from the local hard drive than from other locations. The idea of executing code locally is significantly different from executing from a remote location. Downloading code, storing it to disk, and executing it has a far different set of semantics and requirements than executing code from a remote location. The general idea is that code that is downloaded, saved, and then run locally is usually inspected and reviewed, for example, with a virus scanner before execution. With CAS, the scenario is reversed. Code executed remotely provides more default security than locally executed code. It is important to understand that CAS is not a replacement for standard security precautions. It is designed to provide a new level of protection around security and maintainability of code. Also, now that you have learned the basics, start including and leveraging Code Access Security within your applications. I think you'll find that it provides a minimum of coding but yields a huge return in terms of security and manageability within your applications.
SideBar
Evidence-Based Security
The .NET Framework introduces a new concept for code security - evidence-based security. Evidence is the inputs to the security policy about the code. Based on the answers to these questions, the security policy can generate an appropriate set of permissions. Evidence is obtained from multiple sources that include the CLR, browser, ASP.NET, and even the operating system shell depending on the source code.
Where was the assembly obtained?
Assemblies are considered the basic building blocks of .NET Framework applications. They are the basis for deployment, version control, reuse, activation, and scoping and security authorization. Assemblies are downloaded to the client from a Web site.
.NET Framework Permission Structure
The .NET Framework with Code Access Security provides a variety of permissions that you can request within your code. The following is a guide to the various permission requests available.
| Permission request | Description |
|---|---|
| Minimum permissions (RequestMinimum) | Permissions your code must have in order to run. |
| Optional permissions (RequestOptional) | Permissions your code can use, but can run effectively without. |
| Refused permissions (RequestRefuse) | Permissions that you want to ensure will never be granted to your code, even if security policy allows them to be granted. |
| Perform any of the above requests on built-in permission sets. | Built-in permission sets, including: Nothing, Execution, FullTrust, Internet, LocalIntranet, and SkipVerification. |
| Perform any of the above requests on XML-encoded permission sets. | XML representation (either a string containing the XML-encoded permission set, or the location of an XML file containing the encoded permission set) of a desired permission set. |
Published February 24, 2003 Reads 20,348
Copyright © 2003 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Thom Robbins
Thom Robbins is a senior technology specialist with Microsoft. He is a frequent contributor to various magazines, including .NET Developer's Journal and SOA Web Services Journal. Thom is also a frequent speaker at a variety of events that include VS Live and others. When he's not writing code and helping customers, he spends his time with his wife at their home in New Hampshire.
- The Top 150 Players in Cloud Computing
- Commercial vs Federal Cloud Computing
- Why IBM’s Server Chief Got Busted
- Industry Experts Discuss the State of Cloud Computing
- Cloud Expo New York Call for Papers Deadline December 15
- Cloud Computing on Gartner's Top 10 List and SYS-CON Events' 2010 Calendar
- US Federal Government is Major Cloud Computing Innovator
- Google Wave
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- Adaptivity & Cloud Computing: Exclusive Q&A with CEO Tony Bishop
- 4th International Cloud Expo: Photo Album
- The Top 150 Players in Cloud Computing
- SYS-CON.TV: Cloud Computing Expo Power Panel
- Commercial vs Federal Cloud Computing
- Why IBM’s Server Chief Got Busted
- 1st Annual GovIT Expo: Letter from the Technical Chair
- Deputy CIO of the CIA to Keynote 1st Annual GovIT Expo
- Industry Experts Discuss the State of Cloud Computing
- SOA World Power Panel on SYS-CON.TV
- CIA was Headed to an Enterprise Cloud All Along: Jill Tummler Singer
- 1st Annual Government IT Conference & Expo: Themes & Topics
- Cloud Expo New York Call for Papers Deadline December 15
- Stock in Focus: Dragon Capital
- The i-Technology Right Stuff
- Who Are The All-Time Heroes of i-Technology?
- Get the Message
- Where Are RIA Technologies Headed in 2008?
- i-Technology Viewpoint: Is Web 2.0 the Global SOA?
- i-Technology Viewpoint: Thinking Outside the VC Box
- ESB Myth Busters: 10 Enterprise Service Bus Myths Debunked
- i-Technology Viewpoint: When to Leave Your First IT Job
- SOA Web Services Edge Conference Coverage on SYS-CON.TV
- Five Reasons Why Web 2.0 Matters
- SYS-CON.TV's "SOA Web Services" and "Enterprise Open Source" Programs To Air in December
- SOA World Conference & Expo SYS-CON.TV Power Panel Live From Times Square









There are a variety of applications that supp...

























