Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

ReflectionPermission requirements in anything but Full Trust in ASP.NET


:P
On this page:

I ran into a bit of a revelation today when I got a message from a customer who had been running our West Wind Web Store in development and ran into a number of issues when deployed on the server. As it turns out the ISP had turned down security to low and this is causing the application to fall down all because a lack of Reflection permissions on protected types.

 

I use a custom databinding scheme in my Web pages and this mechanism requires Reflection that usually binds object on a Page object to a control property. The problem is that these properties are generally defined as protected.

 

It turns out that Reflection has some limitations in any but the full trust permission set. Specifically Reflection is not allowed on any non-public types by default, which is configured through the ReflectionPermission security attribute.

 

The databinding usually ends up binding Business object Entity object properties to the various page controls and the problem is that the business object or other object like say a Configuration object tend to be protected objects on the page defined like:

 

protected busCustomer Customer = null;

 

Reflection requires non-public access to retrieve the property from the Page object without the Reflection permission.

 

The quick fix to the problem is to change the code use public references for the objects to be bound:

 

public busCustomer Customer = null;

 

and the problem went away. While that's not a terrible compromise and something I'll keep in mind for the future of the application and making it run under the widest possible security configurations, I wanted to at least figure out which permissions need to get set and how to do it.

 

To switch permission sets you change the security policy settings in the web.config file. You can do this in your local web.config file, if the machine.config isn't set to prevent overriding (as surely on an ISP site it would be).

 

So what I did is copy the webmediumtrust.config file in the .NET Framework config directory and copy it into my Web root. Again – if you're doing this at the machine or enterprise level you'd have to set this file up right in the .NET configuration directory.

 

In Web.config I can then change the policy file:

 

<configuration>

      <system.web>

    <!-- Use this security policy if you need to lower permissions

         Please note the West Wind Web Store will run all the way down to Low

         security but you need to add ReflectionPermission.

    -->

            <securityPolicy>

                  <trustLevel name="WebStoreMedium" policyFile="web_mediumtrustReflection.config"/>

            </securityPolicy>

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

      </system.web>

</configuration>

 

The file copied requires a couple of changes. The first is to add the ReflectionPermission security class to the supported classes:

 

<SecurityClass Name="ReflectionPermission"

               Description="System.Security.Permissions.ReflectionPermission, mscorlib, Version=2.0.0.0, Culture=neutral,

               PublicKeyToken=b77a5c561934e089"/>

 

Next is adding the actual permission to the permission set into the ASP.Net permission set:

 

<IPermission class="ReflectionPermission"

             version="1"

             Unrestricted="true" />

 

Save and run the app and the new policy should now work. This fix gets around this particular limitation.

 

From a security POV I'm not really sure how much of a compromise this is. Obviously it is considered a thread in that all but full trust (including HighTrust) don't allow it.

 

It's not a huge problem anyway – I'll move around the various binding members to public to make this work, but there are a number of other places I use Reflection in this way (optional though – like discovering control names for error messages) where there simply is no other choice I can think of…


The Voices of Reason


 

Jason Haley
May 22, 2006

# Interesting Finds: May 22, 2006 PM edition


Jason Haley
May 22, 2006

# Interesting Finds: May 22, 2006 PM edition


Nicole Calinoiu
May 23, 2006

# re: ReflectionPermission requirements in anything but Full Trust in ASP.NET

Allowing reflection into low visibility members is quite high risk, and it's not something that hosting providers should be willing to do even if they've applied other measures for application isolation. For example, there are private fields in BCL libraries that are used to cache CAS permission definitions. A web application with adequate ReflectionPermission could change these field values, thereby potentially allowing the application to perform actions outside its intended CAS grant.

If you can't avoid reflecting into low visibility members, it might be worth moving just your custom data binding code into a separate assembly that could be granted elevated CAS permissions by GACing or other means. Keeping the code base small and using transparency and assembly-level permission attributes to restrict the CAS permission grant would make code review easier, thereby increasing the chances that any given host might be willing to run the assembly with elevated permissions.

Rick Strahl
May 23, 2006

# re: ReflectionPermission requirements in anything but Full Trust in ASP.NET

Hi Nicole,

The code that does the Reflection code access is limited to a single assembly. It could easily be GAC'd if necessary, but man that sounds like sidestepping the whole security issue, because now you're simply proxying into this GAC'd component to get the same functionality. That's maybe even bigger of a risk because now that component becomes available to every app on the machine.

I think in my case the solution is to bite the bullet and make sure that all items that are bound via the DataBinder are public. Not my choice but I don't see a real problem with this.

The bigger problem is to communicate that 'message' to others using the DataBinder. It'll likely work just fine during development for most - but then at runtime it might fail due to the policy setting.


Nicole Calinoiu
June 08, 2006

# re: ReflectionPermission requirements in anything but Full Trust in ASP.NET

(Sorry for the delay in responding--for some reason, my RSS reader wasn't picking up the comments on this post, and I didn't see your answer.)

If you're willing to go the partial trust route, you don't necessarily need to resort to making the fields public (which could pose some additional risk in shared hosting scenarios where application isolation is not properly implemented). A somewhat more palatable option might be to use internal visibility instead, then expose the internals to your data binder assembly by marking the web page assembly with InternalsVisibleToAttribute. Encapsulation will still be a broken (or at least a bit bent), but the consequences won't be quite as severe as with public accessibility.

# DotNetSlackers: ReflectionPermission requirements in anything but Full Trust in ASP.NET

# What do you want to program today?: How to: Execute (another's class) private methods


Sean
January 04, 2011

# re: ReflectionPermission requirements in anything but Full Trust in ASP.NET

To solve this problem for XBAP's

1) Open the Properties for the WPF XBAP project file
2) Select the Security tab
3) Enable ClickOnce Security Settings
4) Select 'This is a partial trust application'
5) Zone should be 'Local Intranet'
6) Change the Setting for ReflectionPermission to 'Include'

You should see a red exclamation mark appear to the right of the ReflectionPermission line; this is correct. You should be able to run the app now without it blowing up on reflection errors.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024