Controlling Trust Within the Hosted Environment

for RuBoard

A host written in this fashion already has a high degree of control over the assembly loaded in its subdomains. Such assemblies cannot enumerate the other appdomains in the process (unless the host hands them appdomain instances explicitly) and therefore cannot initiate contact with any code in any other appdomain (except any they created themselves ). Together with the type safety guarantees provided by the runtime (given that all code is verifiable or trusted enough to use non-type safe code responsibly), this means that appdomains serve as a mechanism to isolate groups of assemblies even though they share the same process (and, hence, memory address space).

A host can further control assemblies by limiting the trust level associated with its code. This is useful in situations where the security policy system can't be relied on to make the right decision. This might be the case if hosted assemblies are loaded from the local machine but might well come from an untrusted source (the user has manually downloaded them from the Internet, for example). Default security policy will probably ascribe a great deal of trust to an assembly loaded from the local machine (it considers this to be equivalent to having the assembly installed and thus granted implicit trust). If the hosting environment thinks there is a likelihood that users will unthinkingly copy such assemblies directly to their disk and, in fact, knows that there is no reason to grant such assemblies more than a basic set of rights, it can manipulate the security system to lock down the level of trust provided to assemblies it loads.

There are two main methods that a hosting environment can use to achieve this result:

  • Override the evidence used to resolve security policy for an assembly. This is achieved through overloads of AppDomain.Load and Assembly.Load that take an additional System.Security.Policy.Evidence parameter.

  • Add an additional level of policy specific to a single appdomain using the AppDomain.SetAppDomainPolicy method. This policy level is then merged with the enterprise, machine, and user levels that are already taken into consideration by the security policy system.

Both these methods, because they modify the actions of the security system itself, require a high level of trust to implement ( SecurityPermission.ControlEvidence to supply evidence and SecurityPermission.ControlDomainPolicy to add a new policy level).

Let's look at supplying additional evidence first. The following is a simple example:

 using System; using System.Reflection; using System.Security; using System.Security.Policy; class LoadWithEvidence {     public static void Main(String[] args)     {         // Create a new evidence container and add zone evidence         // referencing the Internet zone.         Evidence evidence = new Evidence();         evidence.AddHost(new Zone(SecurityZone.Internet));         // Load an assembly with this additional evidence. Regardless         // which zone the load really occurs from, the Internet zone         // will be used by the security system when resolving policy         // into a trust level.         Assembly.Load("MyHostedAssembly", evidence);     } } 

This code represents a common technique, overriding the download zone of the assembly so the policy system no longer thinks the assembly was loaded locally and amends the granted permissions accordingly . The additional evidence supplied in the call to Load is merged with the evidence the runtime implicitly derives for the assembly. Where there is a conflict (such as the Zone evidence previously supplied), the evidence provided on the call overrides the implicit evidence.

One potential problem with supplying additional evidence is the transitive loading of additional assemblies. That is, the additional evidence provided on the original load of the assembly is not applied to any load requests that assembly subsequently makes (either implicitly through early bound references or explicitly through a call to Load or similar methods). This is probably the behavior you want when such references are to standard libraries (such as System.Xml ), but if the reference is to a second user assembly downloaded along with the first, this offers a simple method whereby malicious code can side-step the trust restraints you carefully set up.

Therefore, the additional evidence method should only be used when there are constraints on the loaded assembly (for example, it is loaded from a private directory with no other assemblies present).

Now let's look at the other possibility ”adding a domain-specific policy level. This action can only occur once per appdomain (attempting to set it a second time will result in a PolicyException ). Assemblies (such as your host control assemblies) can be loaded into the appdomain prior to adding the policy level, and they will have their grant sets computed normally. After the call to SetAppDomainPolicy is made, any further assemblies loaded will have their grant set calculated taking into account the new level. This includes any assemblies that are transitively loaded (either explicitly or implicitly) by these assemblies. So this method of trust control differs from the additional evidence technique in that respect. Because of this, you will want to pre-load any standard library assemblies that require a high degree of trust before making the call to SetAppDomainPolicy .

The following is an example of the steps a host control assembly might take to prepare a new appdomain for use by hosted assemblies:

 // Create a new appdomain. AppDomain domain = AppDomain.CreateDomain("NewDomain"); // Load our control class into the new appdomain. HostControl control; control = (HostControl)     domain.CreateInstanceAndUnwrap("HostControlAssembly",                                    "HostControl"); // Instruct the control class to load commonly used library // assemblies into the new domain. control.Load("System.Xml, " +              "Version=1.0.5000.0, " +              "Culture=neutral, "+              "PublicKeyToken=b77a5c561934e089"); control.Load("System.Data, " +              "Version=1.0.5000.0, " +              "Culture=neutral, "+              "PublicKeyToken=b77a5c561934e089"); // Define the set of permissions we're going to allow new // assemblies (this will be intersected with the results from // the other policy levels, so it's a maximum). PermissionSet allowed; SecurityPermission sp; allowed = new PermissionSet(PermissionState.None); sp = new SecurityPermission(SecurityPermissionFlag.Execution); allowed.AddPermission(sp); // Create a policy statement that associates the permission // set above with an attribute describing how the policy level // should interact with others (we'll take the default -- // PolicyStatementAttribute.Nothing). PolicyStatement ps = new PolicyStatement(allowed); // Create an appdomain policy level that matches all // assemblies and assigns them the permissions we // computed earlier (just SecurityPermission.Execution). PolicyLevel level = PolicyLevel.CreateAppDomainLevel(); CodeGroup group; group = new UnionCodeGroup(new AllMembershipCondition(),                            ps); // Add the new policy level to the target appdomain. domain.SetAppDomainPolicy(level); // Now we can begin loading hosted assemblies. control.Load("MyHostedAssembly"); 
for RuBoard


. NET Framework Security
.NET Framework Security
ISBN: 067232184X
EAN: 2147483647
Year: 2000
Pages: 235

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