Application Domain Crossing Issues
To isolate code in managed hosting environments, it is common to generate multiple child application domains with explicit policy reducing the permission levels for various assemblies. However, the policy for those assemblies remains unchanged in the default application domain. If one of the child application domains can force the default application domain to load an assembly, the effect of code isolation is lost and types in the forcibly loaded assembly will be able to run code at a higher level of trust.
An application domain can force another application domain to load an assembly and run code contained therein by calling a proxy to an object hosted in the other application domain. To obtain a cross-application-domain proxy, the application domain hosting the object must distribute one through a method call parameter or return value. Or, if the application domain was just created, the creator has a proxy to the AppDomain object by default. Thus, to avoid breaking code isolation, an application domain with a higher level of trust should not distribute references to marshaled-by-reference objects (instances of classes derived from MarshalByRefObject) in its domain to application domains with lower levels of trust.
Usually, the default application domain creates the child application domains with a control object in each one. The control object manages the new application domain and occasionally takes orders from the default application domain, but it cannot actually contact the domain directly. Occasionally, the default application domain calls its proxy to the control object. However, there might be cases in which it is necessary for the control object to call back to the default application domain. In these cases, the default application domain passes a marshal-by-reference callback object to the constructor of the control object. It is the responsibility of the control object to protect this proxy. If the control object were to place the proxy on a public static field of a public class, or otherwise publicly expose the proxy, this would open up a dangerous mechanism for other code to call back into the default application domain. For this reason, control objects are always implicitly trusted to keep the proxy private.