Share via


Running ASP.NET in a Shared Hosting Environment

I was recently working on an issue with a large international hosting company. This company hosts many websites in a shared hosting environment, and one of their customers had uploaded a page that performed some tasks using ASP.NET that greatly concerned them.

The ASP.NET page allowed the following when it was browsed:

  • Browsing of files in the Windows directory using the System.IO namespace.
  • Browsing of folders in the Program Files directory using the System.IO namespace.
  • Browsing of files in the System32 directory using the System.IO namespace.
  • Output of the OS name and version number using the Environment class.
  • Output of the physical disk path (including one on an external file server) for the website's content using Server.MapPath.
  • Output of the server's local IP address using server variables.

These capabilities are not unique to ASP.NET. Most server-side programming technologies allow for the same functionality. However, my customer was concerned over exposing this much information about his internal environment and he wanted me to do something about it!

As you certainly know, ASP.NET runs inside of the CLR (Common Language Runtime), and because of that, ASP.NET is able to take advantage of the CLR's capabilities. One of those capabilities is a powerful security architecture that makes it easy to define the capabilities of a .NET Framework application.

By default, ASP.NET runs under full trust. That means that an ASP.NET application has a lot of powerful functionality, some of which might not be desirable in a shared hosting environment. The solution to my customer's problem was to change ASP.NET to run under medium trust. When running under medium trust, an ASP.NET application runs in a much more restricted environment. Among other restrictions, running under medium trust prevents an ASP.NET application from accessing any directories outside of the application's own directory structure.

To run ASP.NET under medium trust, a simple change is made to the default web.config file located in the Microsoft.NET\Framework\v2.0.50727\Config folder. The specific change you should make is in the following section.

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

The first change you'll want to make is to set the allowOverride attribute to false.By making that change, you prevent an ASP.NET developer from overriding your change in his or her own web.config file. After making that change, you'll need to change the trust level from Full to Medium. Once you'd made those changes, the new section looks like the following. Changes appear in bold text.

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

Notice that the <trustLevel> element defines which configuration file contains the specific configuration settings for the specific trust level. The configuration for medium trust is contained a file called web_mediumtrust.config which is also located in the Config folder.

You can modify the web_mediumtrust.config file if you want more precise control over your security model. For example, my customer was concerned that ASP.NET developers were able to use the Environment class to access the OS name and the computer's netbios name. I was able to resolve that for him by making a modification to the ASP.NET permission set in the web_mediumtrust.config file.

<IPermission
     class="EnvironmentPermission"
     version="1"
     Read="TEMP;TMP;USERNAME;OS;COMPUTERNAME"
/>

By removing OS and COMPUTERNAME from the Read attribute of this element, I was able to prevent ASP.NET developers from accessing the information that concerned my customer.

You can read more about other limitations that this method imposes along with many more details in the following MSDN article.

https://msdn2.microsoft.com/en-us/library/ms998341.aspx

If you're interested in performing these same steps in ASP.NET 1.1, you can get details on doing so by watching the following video.

https://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20050317ASPNETSS/manifest.xml

Jim

Comments

  • Anonymous
    September 30, 2007
    PingBack from http://www.artofbam.com/wordpress/?p=4049

  • Anonymous
    September 30, 2007
    A nice article about some problems which may facing you if you plan to running your asp.net application

  • Anonymous
    October 01, 2007
    It is important to note that medium trust prevents the use of reflection. Which is used with the DataBinder.Eval method.

  • Anonymous
    October 01, 2007
    DataBinder.Eval will work. Running in medium trust prevents the use of the ReflectionPermission, but that's not the same thing as preventing the use of reflection. While DataBinder.Eval does use reflection, it does not require the ReflectionPermission. Hope that helps to clarify that point. Our article is not technically accurate in saying that the use of reflection is not allowed. Jim

  • Anonymous
    October 01, 2007
    I've done some more looking into this. The following blog post should make it much clearer: http://blogs.msdn.com/shawnfa/archive/2005/03/08/389768.aspx Thanks to Scott Hanselman (http://www.hanselman.com/blog/) for pointing me to this. Jim

  • Anonymous
    October 23, 2007
    Hi Jim, You reminded me of back in the ASP.NET 1.1 days with GoDaddy - I had to do similar things to get community server running (before they officially supported it).  Because they were running under FullTrust, I ended up writing a script to use the security impersonation features to impersonate a local windows user (I guessed my supplied FTP login would have the needed credentials), and then changed many permissions of my files and did needed SQL stuff.  This was many years ago, and I cannot remember the details, but now most hosts are using .NET 2 and run in medium trust. Of course - the code access security is also a huge issue for ASP.NET success in the market if every hosting company defines different permission sets and applications end up only running on a small set of shared hosting providers.  Try searching for the trust level for the main hosting companies and most do not even publish it.  So if you want to host ASP.NET apps, you basically have to pony up the money and 'hope' your app will work, only to find out later that you get some random security permission (ie DnsPermission, or something else). Another example is that MediumTrust does not even allow outbound http connections to 3rd party servers which is a requirement of almost any modern web app that calls external web services or aggregates feeds, etc.  (GoDaddy for example has added that permission to MediumTrust to satisfy customers). I think Microsoft needs to get the top 10 hosters together and agree on some minimum hosting level and give it a marketing name like "ASP.NET Hosting Supported" (maybe Medium Trust plus a few other permissions).  Hosters should only be able to use the label if they support it as a minimum.  Then applicaitons (like Community server, etc) can say "ASP.NET Hosting Supported" along with a logo or something. That would definately help ASP.NET in the market.

  • Anonymous
    October 25, 2007
    That's not a bad idea, David. Thanks for the feedback. Jim

  • Anonymous
    August 07, 2008
    The comment has been removed

  • Anonymous
    August 11, 2008
    Kunal, This is happening because the WebChart control requires some permission that is not permitted due to the CLR security settings at your host. If I were to guess (which is really all I can do based on what you know,) I would say that your host is running in Medium Trust and the WebChart control does not work in that kind of environment. The most common cause of this is when an assembly contains mixed-mode code (a mixture of managed and unmanaged code.) Such assemblies require Full Trust. It is possible to assign Full Trust to a specific assembly, but doing so would require that the assembly be strong-named (the one you are using is not) and you'd also need to work with your host on editing the configuration. I'm afraid in order to get full information and assistance in getting this to work, you will need to contact the vendor of the control. Hope that helps. Jim

  • Anonymous
    October 10, 2008
    I was planning on using a sample .net2.0 theme and just doing some simple redesign on it but I was hit with this medium trust issue it seems. It works fine on my former host provider but I switched to save some serious $. I would like to get this to work so I need some help converting it to work within the medium trust settings. Imports System.CodeDom Imports System.ComponentModel Imports System.Web.Compilation Imports System.Web.Configuration Imports System.Configuration <ExpressionPrefix("Themes")> _ Public Class ThemesExpressionBuilder    Inherits System.Web.Compilation.ExpressionBuilder    Private Const STYLESHEET_THEME As String = "stylesheettheme"    Private Const THEME As String = "theme"    Public Overrides Function GetCodeExpression(ByVal entry As System.Web.UI.BoundPropertyEntry, ByVal parsedData As Object, ByVal context As System.Web.Compilation.ExpressionBuilderContext) As System.CodeDom.CodeExpression        Dim expressionArray(0) As CodeExpression        expressionArray(0) = New CodePrimitiveExpression(entry.Expression.Trim())        Return New CodeMethodInvokeExpression(New CodeTypeReferenceExpression(MyBase.GetType()), "GetEvalData", expressionArray)    End Function    Public Overrides ReadOnly Property SupportsEvaluate() As Boolean        Get            Return True        End Get    End Property    Public Overrides Function EvaluateExpression(ByVal target As Object, ByVal entry As System.Web.UI.BoundPropertyEntry, ByVal parsedData As Object, ByVal context As System.Web.Compilation.ExpressionBuilderContext) As Object        Return GetEvalData(entry.Expression)    End Function    Public Shared Function GetEvalData(ByVal expression As String) As Object        Dim result As String = String.Empty        ' Get the Web application configuration.        Dim config As Configuration = WebConfigurationManager.OpenWebConfiguration("")        ' Get the 'pages' section.        Dim pagSection As PagesSection = CType(config.GetSection("system.web/pages"), PagesSection)        Dim hasArgs As Boolean = System.Text.RegularExpressions.Regex.IsMatch(expression, ".+(.+)", RegexOptions.IgnorePatternWhitespace Or RegexOptions.Compiled Or RegexOptions.IgnoreCase)        'Determine the expression result        If expression.ToLowerInvariant().StartsWith(STYLESHEET_THEME) Then            If hasArgs Then                expression = expression.Substring(STYLESHEET_THEME.Length + 1, expression.Length - STYLESHEET_THEME.Length - 2)                Dim helper As System.Web.UI.Control = New Control()                result = helper.ResolveUrl(String.Format(expression, pagSection.StyleSheetTheme))            Else                result = pagSection.StyleSheetTheme            End If        ElseIf expression.ToLowerInvariant().StartsWith(THEME) Then            If hasArgs Then                expression = expression.Substring(THEME.Length + 1, expression.Length - THEME.Length - 2)                Dim helper As System.Web.UI.Control = New Control()                result = helper.ResolveUrl(String.Format(expression, pagSection.Theme))            Else                result = pagSection.Theme            End If        End If        Return result    End Function End Class

  • Anonymous
    August 04, 2009
    Full trust hosting? check http://www.webhost4lifereview.com/full-trust-web-hosting/

  • Anonymous
    August 03, 2010
    hi jim, I am currently experiencing some trouble with my current hosting provider that whenever i call 3rd party webservices, REST based webservice to external server ( which works fine in my local system ) then it said 401 un-authorized. Do you believe that it's the restricted trust level case ?