Return to ASPNET2SecurityHowTos


How To: Use Medium Trust 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 explains how you can run ASP.NET Web applications in Medium trust. If you host multiple applications on the same server, you can use code access security and the Medium trust level to provide application isolation. By setting and locking the trust level in the machine-level Web.config file, you can establish security policy for all Web applications on the server. Running at Medium trust with ASP.NET 2.0 is easier than it was with 1.1 because you now have access to SQL Server databases. Medium trust still provides a constrained environment for isolating applications from one another and from shared server resources. Medium trust applications have no registry access, no event log access, no ability to use reflection, Web access is limited to the host server and file system access is limited to the application's virtual directory hierarchy. If Medium trust policy is too restrictive, you can create and use a custom policy file.

Contents

* Overview
* What's New with Medium Trust?
* Configuring Medium Trust
* Locking the Trust Level
* Modifying Medium Trust Policy
* OleDbPermission
* EventLogPermission
* FileIOPermission
* Developing for Medium Trust
* Permcalc
* Additional Considerations

Overview

By default ASP.NET 2.0 Web applications and Web services run with full trust and applications can perform privileged operations and access resources subject only to operating system security and Windows access control lists (ACLs).
To lock down your ASP.NET application and to provide an additional degree of application isolation in a hosted environment, you can use code access security to restrict which resources it can access and which privileged operations it can perform. You do this by configuring the <trust> element as shown below.
		 <trust level="Full|High|Medium|Low|Minimal" />
	
The <trust> element supports a number of default trust levels. Each level in succession provides a more restrictive environment (with fewer code access security permissions) in which to run your application.
ISPs that need to host multiple applications from many different companies often use the Medium trust level to help ensure that applications cannot read each others data or interfere with one another in any way. Medium trust also places restrictions on the types of shared system resources that the applications can access.

What's New in 2.0?

Medium applications ASP.NET 2.0 can now access SQL Server databases because the SQL Server Managed Data Provider no longer demands full trust and the SqlClientPermission is granted to Medium trust applications. Medium trust applications are now also grants the new SqlNotificationPermission, which enables them to receive notifications from SQL Server.
The main constraints placed on Medium trust Web applications are:
* OleDbPermission is not available which means you cannot use the ADO.NET managed OLE DB data provider to access databases. You can however use the managed SQL Server provider to access SQL Server databases.
* EventLogPermission is not available which means you cannot access the Windows event log.
* ReflectionPermission is not available which means you cannot use reflection.
* RegistryPermission is not available which means you cannot access the registry.
* WebPermission is restricted. Your application can only communicate with the originating host server.
* FileIoPermission is restricted. You can only access files in your application's virtual directory hierarchy. Your application is granted Read, Write, Append, and PathDiscovery permissions for your application's virtual directory hierarchy.

You are also prevented from calling unmanaged code or from using Enterprise Services.

Configuring Medium Trust

To configure an application to run with Medium trust, add the following element to either your application's specific Web.config file in your application's virtual root directory or to the machine level Web.config file.

		 <trust level="Medium" originUrl="" />
	


Note: The originUrl attribute specifies an application's URL of origin. If present, this can be used by some permissions such as WebPermission that allow connectivity back to the host of origin.

To configure all Web applications on a server to run with Medium trust, add this element to the machine level Web.config file located in the following folder:

		 %windir%\Microsoft.NET\Framework\{version}\Config
	

Note that by default, Web applications are configured to run with full trust as shown in the following default configuration from the machine level Web.config 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" />	
		   </securityPolicy>
		   <trust level="Full" originUrl="" />
		 </system.web>
		 </location>
	

To review the full set of permissions available to Medium trust applications, you can view the web_mediumtrust.config file.

Locking the Trust Level

Application service providers or anyone responsible for running multiple Web applications on the same server should apply the Medium trust policy setting in the machine level Web.config file and then lock the trust level for all Web applications.
To do this, set the allowOverride attribute to false in the machine level Web.config file, as shown below.

		 <location allowOverride="false">
		 <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" />	
		   </securityPolicy>
		   <trust level="Medium" originUrl="" />
		 </system.web>
		 </location>
	

By setting allowOverride="false" an individual developer is unable to override the Medium trust policy setting in their application's Web.config file.

Modifying Medium Trust Policy

If Medium trust proves too restrictive, you can create a custom policy file based on the Medium trust policy. For example, you might want allow applications to connect to an Oracle database, you might want to allow applications to write events to the Windows event log, or you might want to allow applications to read files from a specified directory outside of the application's virtual directory hierarchy.
Common permissions that you might need to add include:
* OleDbPermission
* EventLogPermision
* FileIOPermission

To create a custom policy based on Medium trust:

1. Copy the Medium trust policy file webMediumTrust.config located in the following directory to create a new policy file in the same directory. Name it something to indicate that it's your variation for example customWebMediumTrust.config.

		 \Windows\Microsoft.NET\Framework\{Version}\Config
	

2. Add the additional permissions that you want to grant. In the following example, the FileIOPermission is modified to allow read access to a specific directory outside of the application's virtual directory hierarchy.

		 [<PermissionSet]
		    class="NamedPermissionSet"
		    version="1"
		    Name="ASP.Net">
		  . . .
	
<IPermission
		  	   class="FileIOPermission"
		       version="1"
		  	   Read="C:\<DirectoryName>"
		  	   Write="$AppDir$"
		  	   Append="$AppDir$"
		  	   PathDiscovery="$AppDir$"
		 />
		  . . .
		 [</PermissionSet>]
	

3. Create a new custom policy level in your machine-level Web.config. The policy file is the name of the policy file you just created.

		 <securityPolicy>
		  <trustLevel name="CustomMedium" 
		              policyFile="customWeb_mediumtrust.config" />
		  . . .
		 </securityPolicy>
	

4. Configure applications to run at the new custom policy level by setting the trust level to "CustomMedium". Your security policy will resemble the following.

		 <system.web>
		  <securityPolicy>
		   <trustLevel name="CustomMedium"
		               policyFile="customWeb_mediumtrust.config" />
		   <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" />
		 </securityPolicy>
		 <trust level="CustomMedium" originUrl="" />
	
</system.web>

OleDbPermission

If you support multiple database server types, you need to grant OleDbPermission to Web applications in addition to SqlClientPermission, which is already granted by Medium trust policy.

To extend Medium trust policy to grant OleDbPermission:

1. Create a custom policy file and configure your application to use the custom trust level as described above.
2. Add the following permission class to the <SecurityClasses> section.

		 [<SecurityClass] Name="OleDbPermission" 
		  Description="System.Security.Permissions.OleDbPermission, mscorlib, Version=2.0.0.0, Culture=neutral,  PublicKeyToken=b77a5c561934e089"/>
	

3. Add the unrestricted OleDbPermission to the ASP.Net named permission set.

		 [<PermissionSet]
		    class="NamedPermissionSet"
		    version="1"
		    Name="ASP.Net">
		  . . .
		     [<IPermission] class="OleDbPermission" 
		                  version="1" 
		                  Unrestricted="true"/>
		     . . .
		   [</PermissionSet>]
	

EventLogPermission

Medium trust policy does not permit access to the Windows event log.

To enable access to the event log:

1. Create a custom policy file and configure your application to use the custom trust level as described above.
2. Add the following permission class to the <SecurityClasses> section.

		 [<SecurityClasses>]
		  ...
		  [<SecurityClass] Name="EventLogPermission"
		                 Description="System.Diagnostics.EventLogPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
		  ...
		 [</SecurityClasses>]
	

3. Add the following <IPermission> element to the ASP.Net named permission set.

		 [<PermissionSet]
		    class="NamedPermissionSet"
		    version="1"
		    Name="ASP.Net">
		  . . .
		     [<IPermission]
		          class="EventLogPermission"
		          version="1">
		        <Machine name="."
	
access="Write"/>
		     [</IPermission>]
		     . . .
		   [</PermissionSet>]
	

Note:<<Write doesn’t actually allow write – you need to set this to Administer on build 45 – open issue.>>

Creating Event Sources

If your application needs to create event sources, you need to ensure that the application's identity has the relevant permissions on the following registry key.

		 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog
	

At minimum, your Web application process identity, which defaults to Network Service on Windows Server 2003, must have the following permissions on this registry key:
* Query key value
* Set key value
* Create subkey
* Enumerate subkeys
* Notify
* Read

These settings must be applied to the key shown above and subkeys. Alternatively, you can create event sources at installation time when administrative privileges are available.

Note: Be aware that by enabling access to the Windows event log, you run the risk of another application accessing the same log and interfering with events, for example to cover tracks.

FileIOPermission

If you need to allow your application to access files outside of the application's virtual directory hierarchy, you can create a custom policy file based on the Medium trust file and then modify the FileIOPermission.
For example, the following definition enables an application to read files in the "C:\SomeDir" directory.

		 [<IPermission]
		  class="FileIOPermission"
		  version="1"
		  Read="C:\SomeDir"
		  Write="$AppDir$"
		  Append="$AppDir$"
		  PathDiscovery="$AppDir$"
		 />
	

By letting applications access files beyond the application's virtual directory hierarchy you are diminishing the ability of code access security to provide application isolation. If you have multiple applications on a single server, you need to protect resources such as files with ACLs and use separate identities for each application. For more information, see "Using Application Pool Identities for Isolation" later in this document.

Developing for Medium Trust

To help design and develop your applications for Medium trust, consider the following:

* Identify the types of resources that your application needs to access and the privileged operations it needs to perform.
You need to know which code access security permissions this will mean your application requires. For more information about permission requirements, see "Resource Access Permissions Summary" and "Privileged Operation Permissions Summary" later in this document.
* Know what permissions are available at Medium trust.
The best way to see this is to open and examine web_MediumTrust.config in the following folder.

		 %windir%\Microsoft.NET\Framework\{Version}\Config
	

* Configure your development environment and your application's Web.config for Medium trust.
Do this from the outset of development so that you can immediately see what permission requests fail and what issues need to be addressed.
* For existing applications consider using Permcalc.
If you have an existing application that you now want to run at Medium trust, consider using the Permcalc tool to help you determine precisely which permissions your application needs. You should also ensure that extensive testing is performed to make sure that all code paths through your application have been executed. Failure to do so can lead to unexpected security exceptions at runtime. For more information, see "PermCalc" later in this document.

The best approach is to target your trust level before you begin design and development work and to design and develop specifically for this trust level. Common causes of security exceptions when you switch an existing application to Medium trust include:
* Calling unmanaged code.
* Accessing the registry.
* Writing to the event log.
* Connecting to databases other than SQL Server.
* Accessing Web resources on remote servers.
* Accessing the file system beyond your application's virtual directory hierarchy.

PermCalc

The Permcalc tools helps you to identify the permission requirements of an assembly. If you use separate assemblies for your application's business and data access logic and locate them either in your application's \bin directory or the global assembly cache, 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:

1. Run following command from a Visual Studio .NET 2005 command window.

		 Permcalc -Show <assemblyName>
	

Sample output from this command is shown below
		 <?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>
	

2. 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 follows:

		 Permcalc -Show <assembly1> <assembly2> <assembly3>
	

Using Application Pool Identities for Isolation

If your applications run on Windows Server 2003, you can use multiple application pools and configure each application to run in its own process (w3wp.exe) with its own unique identity. This provides process-level isolation and you can configure ACLs on file system and other resources accordingly.

To use application pools for isolation:

1. Create a set of new Windows accounts, one per application to run each application pool process instance.
2. Configure NTFS permissions for each account to ensure that each account only has access to the appropriate file system files and folders, and cannot access critical resources such as operating system tools.
3. Create new application pools and configure them to run under the new accounts.
Use IIS 6 to create new application pools with default settings, and use the accounts created in step 1 to configure the identity of each pool, so that each pool runs using a separate identity.
4. Configure each application to run in its own application pool.
On the Directory tab of each IIS application, choose the application pool for the application to run in.

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 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

Additional Resources

* "How To: Use Code Access Security in ASP.NET"
* "How To-Expose Resources to Partially Trusted Code"





Return to ASPNET2SecurityHowTos
Microsoft Communities