Medium Trust Restrictions


If your application runs at medium trust, it faces a number of restrictions, the most significant of which are:

  • It cannot directly access the event log.

  • It has restricted file system access and can only access files in the application's virtual directory hierarchy.

  • It cannot directly access OLE DB data sources (although medium trust applications are granted the SqlClientPermission, which allows them to access SQL Server).

  • It has limited access to Web services.

  • It cannot directly access the Windows registry.

This section shows you how to access the following resource types from a medium-trust Web application or Web service:

  • OLE DB

  • Event log

  • Web services

  • Registry

OLE DB

Medium-trust Web applications are not granted the OleDbPermission . Furthermore, the OLE DB .NET data provider currently demands full-trust callers . If you have an application that needs to access OLE DB data sources while running at medium trust, use the sandboxing approach. Place your data access code in a separate assembly, strong name it, and install it in the GAC, which gives it full trust.

Note  

Modifying policy does not work unless you set the trust level to "Full" because the OLE DB managed provider demands full trust.

Figure 9.3 shows the arrangement.

click to expand
Figure 9.3: Sandboxing OLE DB resource access

Sandboxing

In this approach, you create a wrapper assembly to encapsulate OLE DB data source access. This assembly is granted full-trust permissions, which are required to use the ADO.NET OLE DB managed provider.

 Task   To build a sandboxed wrapper assembly to call OLE DB data sources

  1. Create an assembly for your data access code. Configure the assembly version, strong name the assembly, and mark it with the AllowPartiallyTrustedCallersAttribute , as follows :

     [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyKeyFile(@"..\..\oledbwrapper.snk")] [assembly:AllowPartiallyTrustedCallersAttribute()] 

    You must annotate any strong named assembly with AllowPartiallyTrustedCallersAttribute if you want to support partial-trust callers. This suppresses an implicit link demand for full trust made by the .NET Framework whenever code from a strong named assembly is loaded and JIT-compiled.

  2. Request full trust . Although not strictly necessary, requesting full trust is a good practice because it allows an administrator to view the assembly's permission requirements by using tools like Permview.exe. To request full trust, request the unrestricted permission set as follows:

     [assembly: PermissionSet(SecurityAction.RequestMinimum, Unrestricted=true)] 
  3. Wrap database calls with an Assert statement to assert full trust. Wrap a matching RevertAssert call to reverse the effect of the assert. Although not strictly necessary, it is a good practice to place the call to RevertAssert in a finally block.

    Because the OLE DB provider demands full trust, the wrapper must assert fulltrust. Asserting an OleDbPermission is not sufficient. Step 7 explains how to improve the security of using CodeAccessPermission.Assert .

     public OleDbDataReader GetProductList() {   try   {     // Assert full trust (the unrestricted permission set)     new PermissionSet(PermissionState.Unrestricted).Assert();     OleDbConnection conn = new OleDbConnection("Provider=SQLOLEDB; Data Source=(local);" +        "Integrated Security=SSPI; Initial Catalog=Northwind");     OleDbCommand cmd = new OleDbCommand("spRetrieveProducts", conn);     cmd.CommandType = CommandType.StoredProcedure;     conn.Open();     OleDbDataReader reader =            cmd.ExecuteReader(CommandBehavior.CloseConnection);     return reader;   }   catch(OleDbException dbex)   {     // Log and handle exception   }   catch(Exception ex)   {     //  Log and handle exception   }   finally   {     CodeAccessPermission.RevertAssert();   }   return null; } 
  4. Build the assembly and install it in the GAC with the following command:

     gacutil -i oledbwrapper.dll 

    To ensure that the assembly is added to the GAC after each subsequent rebuild, add the following post build event command line (available from the project's properties in Visual Studio.NET) to your wrapper assembly project:

     "C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\gacutil.exe" /i $(TargetPath) 
    Note  

    Any strong named assembly that is called by an ASP.NET Web application or Web service must be installed in the GAC. In this instance, you should install the assembly in the GAC to ensure that it is granted full trust.

  5. Configure your Web application for medium trust. Add the following code to Web.config or place it in Machine.config inside a <location> element that points to your application:

     <trust level="Medium" originUrl=""/> 
  6. Reference the data access assembly from your ASP.NET Web application.

    Since a strong named assembly must be in the GAC and not the \bin directory of a Web application, you must add the assembly to the list of assemblies used in the application if you are not using code behind files. You can obtain the PublicKeyToken of your assembly by using the following command:

     sn -Tp oledbwrapper.dll 
    Note  

    Use a capital “ T switch.

    Then add the following to Machine.config or Web.config:

     <compilation debug="false" >   <assemblies>     <add assembly="oledbwrapper, Version=1.0.0.0, Culture=neutral,              PublicKeyToken=4b06"/>   </assemblies> </compilation> 
    Note  

    In between successive rebuilds of your wrapper assembly, you might need to recycle the ASP.NET worker process because your wrapper assembly, which is installed in the GAC is cached by the ASP.NET process. To recycle the ASP.NET worker process (Aspnet_wp.exe) you can run the IISreset.exe utility.

  7. Protect the code that calls Assert .

    The Assert call means that any code that calls the data access wrapper can interact with the OLE DB data source. To prevent malicious code from calling the data access component and potentially using it to attack the database, you can issue a full demand for a custom permission prior to calling Assert and update the medium-trust policy file to grant your Web application the custom permission. This solution entails a reasonable amount of developer effort.

    For more information about developing a custom permission, see "How To: Create a Custom Encryption Permission" in the "How To" section of this guide.

Event Log

The EventLogPermission class is designed to encapsulate the rights of code to access the event log. Currently, however, code must be granted full trust to be able to access the event log. This means that a medium trust Web application cannot directly access the event log. To do so, you must sandbox your event logging code.

Accessing the Event Log

First, ensure that the process account that is used to run your Web application (or the thread identity if your application is impersonating) is able to create event sources. For this, the process or thread identity must be able to create registry keys beneath the following key:

 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog 

At minimum, the ASP.NET process identity of any impersonated identity 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. For more information about this approach, see "Auditing and Logging" in Chapter 10, "Building Secure ASP.NET Web Pages and Controls."

Sandboxing

To sandbox your event logging code, you create a wrapper assembly to encapsulate event log access. You then install the wrapper assembly in the global assembly cache so that is granted full trust by code access security policy.

 Task   To build a sandboxed wrapper assembly to write to the event log

  1. Create an assembly for your event log code. Configure the assembly version, strong name the assembly, and mark it with the AllowPartiallyTrustedCallersAttribute , as shown in the following example.

     [[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyKeyFile(@"..\..\eventlogwrapper.snk")] [assembly:AllowPartiallyTrustedCallersAttribute()] 

    You must annotate any strong named assembly with AllowPartiallyTrustedCallersAttribute if you want to support partial-trust callers. This suppresses an implicit link demand for full trust made by the .NET Framework whenever code from a strong named assembly is loaded and JIT-compiled.

    Note  

    AllowPartiallyTrustedCallersAttribute is defined in the System.Security namespace, so you must reference this namespace with a using statement.

  2. Request appropriate permissions.

    Although not strictly necessary, requesting appropriate permissions is a good practice because it allows an administrator to view the assembly's permission requirements by using tools like Permview.exe. Since the event log assembly can be accessed from partial-trust callers, this assembly does not need to request a full trust permission set. The assembly in this example only writes to the event log on a specific machine and, therefore, only needs the following permission request:

     [assembly:EventLogPermissionAttribute(SecurityAction.RequestMinimum, MachineName="<machine name>", PermissionAccess=EventLogPermissionAccess.Instrument)] 

    However, if your assembly needs to request full trust, request the unrestricted permission set as follows:

     [assembly: PermissionSet(SecurityAction.RequestMinimum, Unrestricted=true)] 
  3. Wrap event log calls with an Assert statement that asserts full trust and a matching RevertAssert that reverses the effect of the assert. Although not strictly necessary, it is a good practice to place the call to RevertAssert in a finally block. The following code writes an Information entry to the Application log with the text "Writing to the event log":

     try {   string source = "Event Source";   string log = "Application";   string eventText = "Writing to the event log";   EventLogEntryType eventType = EventLogEntryType.Information;       //Assert permission   EventLogPermission eventPerm;   eventPerm = new EventLogPermission(EventLogPermissionAccess.Instrument, "<machinename>");   eventPerm.Assert();       //Check to see if the source exists.   if(!EventLog.SourceExists(source))   {//The keys do not exist, so register your application as a source      EventLog.CreateEventSource(source, log);   }       //Write to the log.   EventLog.WriteEntry(source, eventText, eventType);   }   catch(Exception ex)   {/*Handle exception*/}   finally   {     CodeAccessPermission.RevertAssert();   } 
  4. Build the assembly and install it in the GAC with the following command:

     gacutil -i eventlogwrapper.dll 

    To ensure that the assembly is added to the GAC after each subsequent rebuild, add the following post build event command line (available from the project's properties in Visual Studio.NET) to your wrapper assembly project:

     "C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\gacutil.exe" /i $(TargetPath) 
    Note  

    Any strong named assembly called by an ASP.NET Web application or Web service must be installed in the GAC. Assemblies that are installed in the GAC are granted full trust by default code access security policy.

  5. Configure your Web application for medium trust. Add the following to Web.config or place it in Machine.config inside a <location> element that points to your application:

     <trust level="Medium" originUrl=""/> 
  6. Reference the event log assembly from your ASP.NET Web application.

    Since a strong named assembly must be in the GAC and not the \bin directory of a Web application, then you must add the assembly to the list of assemblies used in the application if you are not using code behind files. You can obtain the PublicKeyToken of your assembly by using the following command:

     sn -Tp eventlogwapper.dll 
    Note  

    Use a capital “ T switch.

    Then add the following code to Machine.config or Web.config:

     <compilation debug="false" >   <assemblies>     <add assembly="eventlogwrapper, Version=1.0.0.0, Culture=neutral,          PublicKeyToken=4b06"/>   </assemblies> </compilation> 
    Note  

    In between successive rebuilds of your wrapper assembly, you might need to recycle the ASP.NET worker process because your wrapper assembly, which is installed in the GAC is cached by the ASP.NET process. To recycle the ASP.NET worker process (Aspnet_wp.exe) you can run the iisreset.exe utility.

  7. Protect the code that calls the Assert method. The Assert call means that any code that calls the event log wrapper is able to interact with the event log. To prevent malicious code from calling the event log wrapper and potentially using it to fill the event log, you can issue a full demand for a custom permission prior to calling Assert and update the medium trust policy file to grant your Web application the custom permission. This solution entails a reasonable amount of developer effort.

    For more information about how to develop a custom permission, see "How To: Create a Custom Encryption Permission" in the "How To" section of this guide.

Web Services

By default, medium-trust policy grants ASP.NET Web applications a restricted WebPermission . To be able to call Web services from your Web application, you must configure the originUrl attribute on your application's <trust> element.

 Task   To call a single Web service from a medium trust Web application

  1. Configure the application to run at medium trust.

  2. Set the originUrl to point to the Web service you want to be able to call, as follows:

     <trust level="Medium" originUrl="http://servername/.*"/> 

The originUrl value is used in the constructor for a System.Text.RegEx regular expression class so that in can perform a match on the URLs that are accessible by the Web service. This RegEx class is used in conjunction with a WebPermission class. The ".*" matches any URL beginning with "http:// servername /".

The originUrl attribute is used when ASP.NET policy is evaluated. It gives a value for the $OriginHost$ substitution parameter. Here is the WebPermission definition from Web_mediumtrust.config:

 <IPermission    class="WebPermission"    version="1">    <ConnectAccess>      <URI uri="$OriginHost$"/>    </ConnectAccess> </IPermission> 

If you do not specify the Web servers accessed by your application, any Web service request will fail with a SecurityException . To call a Web service on the local Web server, use the following configuration:

 <trust level="Medium" originUrl="http://localhost/.*" /> 

If your application needs to access multiple Web services on different servers, you need to customize ASP.NET policy because you can only specify one originUrl on the <trust> element in Web.config or Machine.config.

 Task   To call multiple Web services from a medium-trust application

  1. Copy the Web_mediumtrust.config file, which is in the following directory, to a file called Web_mediumtrust_WebService.config, which is located in the same directory.

     %windir%\Microsoft.NET\Framework\{version}\CONFIG 
  2. Locate WebPermission and add a <URI> element for each server you will be accessing, as follows:

     <IPermission class="WebPermission" version="1">   <ConnectAccess>     <URI uri="$OriginHost$"/>     <URI uri="http://server1/.*"/>     <URI uri="http://server2/.*"/>     <URI uri="http://server3/.*"/>   </ConnectAccess> </IPermission> 

    If you call the Web service using its NetBIOS) name, DNS name, and/or IP address, you must have a separate <URI> element for each URI as shown in the following example.

     <IPermission class="WebPermission" version="1">   <ConnectAccess>     <URI uri="$OriginHost$"/>     <URI uri="http://servername.yourDomain.com/.*"/>     <URI uri="http:// servername/.*"/>     <URI uri="http://127.0.0.1/.*"/>   </ConnectAccess> </IPermission> 
  3. Save the file.

  4. Update your application's Web.config file to point to the newly created policy file. This requires that you create a new trust level and map it to the new policy file. Next, configure the <trust> element of your application to use the new level.

    The following fragment shows the necessary additions to Web.config:

     <system.web>   <securityPolicy>     <trustLevel name="MediumPlusWebPermission"                  policyFile="web_mediumtrust_WebService.config"/>   </securityPolicy>   <trust level=" MediumPlusWebPermission" originUrl=""/> </system.web> 

Using Default Credentials

You might need to call a Web service that uses Windows authentication and specify authentication credentials through the proxy credential cache. For example:

 proxy.Credentials = System.Net.CredentialCache.DefaultCredentials; 

In this case, the ASP.NET application requires the EnvironmentPermission with read access to the USERNAME environment variable. Default medium-trust policy grants this permission to Web applications.

In an ASP.NET server-side scenario, the credentials are obtained from the ASP.NET application's thread or process-level token. If DefaultCredentials are used from a desktop application, the current interactive user 's token is used. The demand for EnvironmentPermission is a risk mitigation strategy designed to ensure that code cannot use the local user's credentials at will and expose them to the network.

Registry

By default, medium-trust Web applications are not granted the RegistryPermission . To configure your application to access the registry, you must either modify ASP.NET policy to grant this permission to your application or develop a sandboxed wrapper assembly that has the necessary permission.

The sandboxing approach is the same as described earlier for OLE DB data sources and the event log.

Customizing Policy

The easiest way to customize policy is to create a custom policy file based on the medium-trust policy file and configure your application to use the custom policy. The custom policy grants RegistryPermission to the application.

 Task   To create a custom policy to allow registry access

  1. Copy the Web_mediumtrust.config file, which is in the following directory, to a file called Web_mediumtrust_Registry.config, which is located in the same directory.

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

    By making a copy and creating a custom policy file, you avoid making changes directly to the Web_mediumtrust.config file. Making changes directly to the default medium trust file affects every application on the machine that is configured for medium trust.

  2. Locate the <SecurityClasses> element and add the following to register the RegistryPermission class:

     <SecurityClass Name="RegistryPermission"                 Description="System.Security.Permissions.RegistryPermission,                 mscorlib, Version=1.0.5000.0, Culture=neutral,                 PublicKeyToken=b77a5c561934e089"/> 
  3. Locate the ASP.NET permission set and add the unrestricted RegistryPermission to the permission set as follows:

     <IPermission class="RegistryPermission" version="1" Unrestricted="true" /> 
  4. Save the file.

  5. Update Machine.config to create a new trust level that is mapped to the new policy file.

     <system.web>   <securityPolicy>     <trustLevel name="MediumPlusRegistry"                  policyFile="web_mediumtrust_Registry.config "/>   </securityPolicy> 
  6. Update your application's Web.config to configure the application's <trust> level.

     <system.web>   <trust level="MediumPlusRegistry" originUrl=""/> </system.web> 



Improving Web Application Security. Threats and Countermeasures
Improving Web Application Security: Threats and Countermeasures
ISBN: 0735618429
EAN: 2147483647
Year: 2003
Pages: 613

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net