Return to
HomePage
Note:
This document is live on MSDN! See http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000017.asp
How To: Use Code Access Security in ASP.NET 2.0
J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley
Microsoft Corporation
May 2005
Applies To
* ASP.NET 2.0
Summary
This How To describes how to use code access security in ASP.NET 2.0 Web applications. If your application calls only managed code, you can use different code access security trust levels to incrementally limit your exposure to security attacks and provide extra degrees of application isolation. Code access security allows you to constrain your Web application by restricting the types of resources it can access and the types of operations it can perform. Code access security is particularly important when your application does not trust other applications that run in a hosted or shared server environment. For example to ensure that applications cannot read each other's private data and cannot access critical shared system resources.
Contents
*
Overview *
Step 1: Identify the Permissions Your Application Needs *
Step 2: Choose an Appropriate Trust Level *
Step 3: Configure Your ASP.NET Application *
Step 4: Optionally Create a Custom Trust Level *
Locking the Trust Level *
Resource Access Permissions Summary *
Privileged Operation Permissions Summary *
ASP.NET Trust Level Summary *
Additional Resources
Overview
ASP.NET 1.1 and 2.0 Web applications and Web services run with full trust by default. When an application runs with full trust, code access security places no restrictions on the resources and operations it can access, and resource access is based solely on operating system security and Windows access control lists (""ACLs"").
To protect your ASP.NET application, you can use code access security to restrict which resources the application can access and which privileged operations it can perform. You do this by configuring the
<trust> element in the application's Web.config file and setting it to one of the predefined trust levels as shown here.
<trust level="Full|High|Medium|Low|Minimal" />
The
<trust> element supports a number of predefined trust levels. Each level in succession provides a more restrictive environment (with fewer code access security permissions) in which to run your application.
For situations where your application requires a set of code access security permissions that do not exactly match one of the predefined trust levels, you need to evaluate whether it makes sense to create a custom trust level or whether you should target the higher trust level. The best choice depends on how close the existing trust level is to meeting the permission requirements of your application.
This How To explains how to select an appropriate trust level for your application, and where necessary, how to create a custom ASP.NET code access security policy file to define a custom trust level.
What Is New with Code Access Security in ASP.NET 2.0?
The default set of trust levels for ASP.NET 2.0 are the same as ASP.NET 1.0. The capabilities available to applications running at the various trust levels are summarized in Table 1.
Table 1. Trust Levels and Their Key Capabilities and Restrictions
| Trust Level | Key Capabilities and Restrictions |
| High | No unmanaged code. |
| | No enterprise services. |
| | Can access SQL Server and other OLE DB data sources. |
| | Very limited reflection permissions. |
| | No ability to invoke code by using reflection. |
| | A broad set of other framework features are available. |
| | Applications have full access to the file system, and to sockets. |
| Medium | Permissions are limited to what the application can access within the directory structure of the application. |
| | No file access is permitted outside of the application's virtual directory hierarchy. |
| | Can access SQL Server. |
| | Can send e-mail by using SMTP servers. |
| | Limited rights to certain common environment variables. |
| | No reflection permissions whatsoever. |
| | No sockets permission. |
| | To access Web resources, you must explicitly add endpoint "URLs" — either in the originUrl attribute of the <trust> element or inside the policy file. |
| Low | Intended to model the concept of a read-only application with no network connectivity. |
| | Read only access for file I/O within the application's virtual directory structure. |
| Minimal | Execute only. |
| | No ability to change the "IPrincipal" on a thread or on the "HttpContext". |
The main differences between ASP.NET 1.1 and ASP.NET 2.0 for the trust levels are the following:
* In version 2.0, SQL Server access is available at Medium trust level because the SQL Server .NET Data Provider no longer demands full trust
* In version 2.0,
SmtpPermission is available at Full, High, and Medium trust levels. This allows applications to send e-mail.
For a detailed set of the code access security permissions that are available at each level see the section, "ASP.NET Trust Level Summary," in this document.
Summary of Steps
*
Step 1: Identify the permissions your application needs. *
Step 2: Choose an appropriate trust level. *
Step 3: Configure your ASP.NET application. *
Step 4: Optionally create a custom trust level.
Step 1: Identify the Permissions Your Application Needs
Identify the precise set of code access security permissions that your application requires. You can do this by manually reviewing your code or by using the Permissions Calculator tool (Permcalc.exe).
Manually Reviewing Code to Identity Permission Requirements
To identify permission requirements manually, you need to analyze your code and determine which types of resources it accesses, what kind of resource access it requires (read/write and so on), and which privileged operations it performs.
The main difficulty with trying to manually identify permission requirements occurs if your code calls other assemblies, such as third-party assemblies or system assemblies. Identifying their permission requirements can be very difficult. This is where the Permcalc tool can help.
For more information about the permissions you need to be able to access specific resources types, see the section, "Resource Access Permissions Summary," in this document.
For more information about privileged operations and the permissions you need to be able to perform them, see the section, "Privileged Operation Permissions Summary," in this document.
Using the Permissions Calculator Tool
If you use separate assemblies for your application's business and data access logic and place them either in your application's \bin directory or the global assembly cache (GAC), then you can run Permcalc on those assemblies. You cannot run Permcalc directly on .aspx Web pages.
To see the permission requirements of an assembly
Run the following command from a Visual Studio .NET 2005 command window.
Permcalc -Show <assemblyName>Sample output from this command is shown here:
<?xml version="1.0" ?>
<Assembly>
<Namespace Name="ClassLibrary1">
<Type Name="Class1">
<Method Sig="instance void test()" />
<Method Sig="instance void .ctor()">
<Demand>
[<PermissionSet] version="1" class="System.Security.PermissionSet">
[<IPermission] version="1" class="System.Security.Permissions.RegistryPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Read="true" />
[<IPermission] version="1" class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Unrestricted="true" />
[</PermissionSet>]
</Demand>
<Sandbox>
[<PermissionSet] version="1" class="System.Security.PermissionSet">
[<IPermission] version="1" class="System.Security.Permissions.RegistryPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Read="true" />
[<IPermission] version="1" class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Unrestricted="true" />
[</PermissionSet>]
</Sandbox>
</Method>
</Type>
</Namespace>
</Assembly>
Examine the permissions listed in the
<Demand> element. These represent the permissions that the assembly needs. In this case, the assembly needs
RegistryPermission and
FileIOPermission.
[<IPermission] version="1" class="System.Security.Permissions.RegistryPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Read="true" />
[<IPermission] version="1" class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Unrestricted="true" />
You can pass a number of assemblies to the Permcalc tool at the same time, as shown in the following command example:
Permcalc -Show <assembly1> <assembly2> <assembly3> Note: If any resource is accessed directly from an .aspx page, you will need to manually calculate the permission requirements for that resource. "PermCalc" works only with assemblies.
Step 2: Choose an Appropriate Trust Level
Try to evaluate whether or not the permissions required for your application match those provided by any of the standard trust levels. If your application calls unmanaged code, it must run with Full trust. Even the least restrictive partial trust level, High, does not permit calls to unmanaged code.
To choose an appropriate trust level
- Examine each trust level beginning with High trust.
- Look inside the High trust policy file, web_HighTrust.config.
- If your application requires fewer code access security permissions than those provided by the High trust level, move on to consider Medium trust.
- Repeat the process, moving from Medium to Low to Minimal, and keep evaluating the partial trust levels until you reach an exact match to your application's requirements or until your application's required permissions slightly exceed a partial trust level.
This process will help you to identify a trust level that matches your application's code access security permission requirements as closely as possible, but does not grant permissions that your application does not need.
Step 3: Configure Your ASP.NET Application
You can configure your ASP.NET application to use a standard trust level either in your application's Web.config file or in the machine Web.config file. Machine-level configuration affects all the ASP.NET Web applications and Web services hosted on that server. Application-level configuration affects only a specific application.
For machine-level configuration, you make changes to the Web.config file located in the following directory:
'%windir%\Microsoft.NET\Framework\{version}\CONFIG\
For application-level configuration, you make changes to the Web.config file located in your application's virtual directory root.
The following example shows how to configure your application for Medium trust.
...
<system.web>
...
<trust level="Medium" originUrl="" />
...
</system.web>
...
Step 4: Optionally Create a Custom Trust Level
You may require a custom trust level if none of the predefined trust levels provide the exact set of permissions that your application needs to run. For example, you may find that your application needs more permissions than Medium trust provides but fewer permissions than High trust provides.
To avoid running with unnecessary permissions, you can either create a custom trust level that provides your exact set of permission requirements or you can wrap your privileged resource access code and grant full trust to the wrapper assembly. The first approach is easier and involves no development effort. However, if you do not want all of the pages in your ASP.NET application to have a particular extended permission granted to them, then you can use a wrapper assembly to control access to your resources.
The two approaches for granting additional permissions to an application beyond those granted by one of the default trust levels are:
*
Customizing trust level policy *
Wrapping privileged code
Customizing Trust Level Policy
With this approach you do the following:
- Copy one of the existing trust level policy files to create a custom policy file.
- Add the required permissions to the custom policy file.
- Configure your application to run using the custom policy.
Note: You are unlikely to be able to use this approach to customize the trust level in hosted environments, where policy restrictions are likely to be rigid.
If you can customize policy, then this is the best option because it does not require any development effort.
In the following example, the application requires all of the permissions provided by Medium trust. In addition, it needs unrestricted access to the Windows registry. While High trust provides unrestricted registry access, it also provides permissions that you may not want to grant to your application, such as unrestricted file I/O access. This is the type of situation where you should consider creating a custom trust level
To create the custom trust level configuration file
* Copy the Medium trust policy file, web
MediumTrust.config, which is located in the %windir%\Microsoft.NET\Framework\{version}\CONFIG\ directory to a file called WebCustomTrust.config in the same directory
* Add the
RegistryPermission security class definition to the
<SecurityClass> section in the Web_CustomTrust.Config file, as shown here:
[<SecurityClass] Name="RegistryPermission" Description="System.Security.Permissions.RegistryPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
* Add the unrestricted
RegistryPermission to the ASP.Net named permission set:
[<PermissionSet]
class="NamedPermissionSet"
version="1"
Name="ASP.Net">
. . .
[<IPermission]
class="RegistryPermission"
version="1"
Unrestricted="true" />
. . .
[</PermissionSet>]
* Modify the
AspNetHostingPermission located near the top of the ASP.Net
<PermissionSet> section to change the Level attribute from
"Medium" to
"Custom" as shown here:
[<IPermission]
class="AspNetHostingPermission"
version="1"
Level="Custom"
/>
* Modify the default Web.config file in the %windir%\Microsoft.NET\Framework\{version}\CONFIG\directory to add the custom trust level that references the custom trust configuration file you have created.
* Add a new
<trustLevel> element to the
<securityPolicy> section of Web.config file to define a new level called
"Custom" and to associate it with the custom policy file.
<location allowOverride="true">
<system.web>
<securityPolicy>
<trustLevel name="Full" policyFile="internal" />
<trustLevel name="High" policyFile="web_hightrust.config" />
<trustLevel name="Medium" policyFile="web_mediumtrust.config" />
<trustLevel name="Low" policyFile="web_lowtrust.config" />
<trustLevel name="Minimal" policyFile="web_minimaltrust.config" />
<trustLevel name="Custom" policyFile="web_CustomTrust.config" />
</securityPolicy>
<trust level="Full" originUrl="" />
</system.web>
</location>
The above changes apply to the root Web.config in the framework CONFIG folder. This applies defaults to all Web applications on the current server.
To configure the trust level for your specific application
- Copy the web_CustomTrust.config file to your application's v-dir.
- Instead of referring to the Web_CustomTrust.config from the machine-level Web.config file, refer to it directly from your application's Web.config, as shown here::
...
<location allowOverride="true">
<system.web>
<securityPolicy>
<trustLevel name="Custom" policyFile="web_CustomTrust.config" />
</securityPolicy>
<trust level="Custom" originUrl="" />
</system.web>
</location>
...
Wrapping Privileged Code
If you do not want all of the pages in your ASP.NET application to have a particular extended permission granted to them, then you can use a wrapper assembly to control access to your resources. With this approach you separate your privileged code into a separate wrapper assembly.
To wrap privileged code
- Identify the precise set of extra permissions beyond those provided by Medium trust that your application needs.
- Place your application's resource access code in a wrapper assembly.
- Grant the wrapper assembly (not the Web application) full trust by strong naming it and installing it into the global assembly cache.
- Add the AllowPartiallyTrustedCallersAttribute (APTCA) to the wrapper assembly to allow it to be called by your partial-trust Web application.
- In the wrapper assembly, assert the permissions which the resource access code needs by calling the Assert method of the CodeAccessPermission class, perform the privileged operation (or access the privileged resource), and then call the RevertAssert method.
For more information, see
HowToWrapPrivilegedCode.
Locking the Trust Level
If a Web server administrator wants to use code access security to ensure application isolation and restrict access to system-level resources, the administrator must be able to define security policy at the machine level and prevent individual applications from overriding it.
Application service providers or anyone responsible for running multiple Web applications on the same server should lock the trust level for all Web applications.
To do this, enclose the
<trust> element in the machine-level Web.config file in a
<location> tag, and set the
allowOverride attribute to
false, as shown in the following example.
...
<location allowOverride="false">
<system.web>
...
<trust level="Medium" originUrl=""/>
...
</system.web>
...
</location>
...
Resource Access Permissions Summary
Table 1 shows which code access security permissions are required to access various resource types.
Table 1: Resources and Associated Code Access Security Permission Requirements
| Resources Accessed | Required Permissions |
| DNS Directory | ""DnsPermission"" |
| Environment Variables | ""EnvironmentPermission"" |
| Event Log | ""EventLogPermission"" |
| File System | ""FileIOPermission"" |
| Isolated File Storage | ""IsolatedStoragePermission"" |
| Message Queues | ""MessageQueuePermission"" |
| OLE DB Data Sources | ""OleDbPermission"" |
| "PerformanceCounters" | ""PerformanceCounterPermission"" |
| Printers | ""PrintingPermission"" |
| Reflection | ""ReflectionPermission"" |
| Registry | ""RegistryPermission"" |
| Security | ""SecurityPermission"" |
| SMTP servers | ""SmtpPermission"" |
| Sockets | ""SocketsPermission"" |
| SQL Server | ""SqlClientPermission"" |
| Web services (and other HTTP Internet resources) | ""WebPermission"" |
Privileged Operation Permissions Summary
Table 2 shows which code access security permissions are required to perform privileged operations.
Table 2: Privileged Operations and Associated Code Access Security Permission Requirements
| Privileged Operation | Required Permissions |
| Creating and controlling application domains | ""SecurityPermission with SecurityPermissionFlag.ControlAppDomain"" |
| Specifying policy application domains | ""SecurityPermission with SecurityPermissionFlag.ControlDomainPolicy"" |
| Asserting security permissions | ""SecurityPermission with SecurityPermissionFlag.Assertion"" |
| Creating and manipulating evidence | ""SecurityPermission with SecurityPermissionFlag.ControlEvidence"" |
| Creating and manipulating principal objects | ""SecurityPermission with SecurityPermissionFlag.ControlPrincipal"" |
| Configuring types and channels remoting | ""SecurityPermission with SecurityPermissionFlag.RemotingConfiguration"" |
| Manipulating security policy | ""SecurityPermission with SecurityPermissionFlag.ControlPolicy"" |
| Serialization | ""SecurityPermission with SecurityPermissionFlag.SerializationFormatter"" |
| Threading operations | ""SecurityPermission with SecurityPermissionFlag.ControlThread"" |
| Reflection | ""ReflectionPermission"" |
| Calling unmanaged code | ""UnmanagedCodePermission"" |
| Call DPAPI to encrypt and decrypt data | ""DpapiPermission"" |
ASP.NET Trust Level Summary
Table 3 shows which code access security permissions are provided by each level. Permissions in ASP.NET 2.0 are highlighted with an asterisk. Note that the main difference between ASP.NET 1.0 and ASP.NET 2.0 permissions is that Medium trust ASP.NET 2.0 applications can access SQL Server and other databases because the
SqlClientPermission is available at Medium trust and the ADO.NET 2.0 SQL Server .NET Data Provider no longer demands full trust.
Table 3 Default ASP.NET Policy Permissions and Trust Levels
| Permission and State | High | Medium | Low | Minimal |
| ""AspNetHostingPermission"" | | | | |
| Level | High | Medium | Low | Minimal |
| ""DnsPermission"" | | | | |
| Unrestricted | """"||"""" | | |
| ""EnvironmentPermission"" | | TEMP; TMP; | | |
| Unrestricted | ""*"" | USERNAME; OS; | | |
| Read | | COMPUTERNAME | | |
| Write | | | | |
| ""EventLogPermission"" | | | | |
| ""FileIOPermission"" | | | | |
| Unrestricted | ""*"" | | | |
| Read | | $AppDir$ | $AppDir$ | |
| Write | | $AppDir$ | | |
| Append | | $AppDir$ | | |
| PathDiscovery | | $AppDir$ | $AppDir$ | |
| ""IsolatedStorageFilePermission"" | | | | |
| Unrestricted | ""*"" | | | |
| AssemblyIsolationByUser | | """"||"""" | |
| ""Unrestricted UserQuota"" | | ""*"" | | 1 MB (can vary with site) |
| ""OleDbClientPermission"" | | | | |
| Unrestricted | | | | |
| ""PrintingPermission"" | | | | |
| Unrestricted | | | | |
| ""DefaultPrinting"" | """"||"""" | | |
| ""ReflectionPermission"" | | | | |
| Unrestricted | | | | |
| ""ReflectionEmit"" | ""*"" | | | |
| ""RegistryPermission"" | | | | |
| Unrestricted | ""*"" | | | |
| ""SecurityPermission"" | | | | |
| Unrestricted | | | | |
| Assertion | """"||"""" | | |
| Execution | """"||"""" | """"||"""" |
| ""ControlThread"" | """"||"""" | | |
| ""ControlPrinicipal"" | """"||"""" | | |
| ""RemotingConfiguration"" | """"||"""" | | |
| ""SocketPermission"" | | | | |
| Unrestricted | ""*"" | | | |
| ""SmtpPermission*"" | | | | |
| Access | | Connect | | |
| ""SqlClientPermission"" | | | | |
| Unrestricted | """"||"""" | | |
| ""SqlNotificationPermission*"" | | | | |
| Unrestricted | | ""*"" | | |
| ""WebPermission"" | | | | |
| Unrestricted | ""*"" | | | |
| ConnectAccess | | $OriginHost$ | | |
Additional Resources
*
How To: Use Medium Trust in ASP.NET 2.0 *
How To: Wrap Privileged Code
Return to
HomePage