In application domains there is such a thing as policies that allow you to restrict the domain rights.

For example, deny access to the file system.

However, does it work in practice?

Is it when Unwarp is made that the assembly from the domain is not loaded into the main domain?

=> if the assembly is malicious, then you can cram some nastiness into the static constructor, for example format c => security collapses, even if the domain was restricted in rights.

Or is not everything so simple, or do domains work differently?

  • Is it when Unwarp is made that the assembly from the domain is not loaded into the main domain? And why are you doing Unwrap ? Cross-border application domains should not transfer objects defined in partially trusted assemblies. For good, partially trusted assemblies should be in a separate path that is not included in the list of paths to search for assemblies for the main domain. - PetSerAl
  • @PetSerAl I do not know the situation of the author, but I can give you an example: you write an application and a plugin system for it; plugins untrusted, must implement a specific interface. For example, the methods bool CanProcess(object) and void Process(object) . You want to load this plugin into a separate AppDomain with restrictions, and call these methods, sure that it will not cause an unexpected deletion of data from the file system. Probably there is a wrong design of the system. - Lunar Whisper
  • @LunarWhisper To be honest, I absolutely did not understand how your comment relates to mine. - PetSerAl

1 answer 1

Yes, Unwrap will load the assembly into the main domain too. Therefore, it is done correctly in another way:

  1. a descendant class MarshalByRefObject is created in the main, trusted assembly;
  2. an instance of this class is loaded in the new domain, and Unwrap is done to it (the trusted instance);
  3. all further interaction with objects in the new domain is done through this object.

For the situation of plug-ins, it makes sense for each interface that can be implemented by the plug-in to prepare your cross-domain proxy for loading in the plug-in domain. In the simplest case, such a proxy will simply delegate all calls:

 class FooCrossDomainProxy: MarshalByRefObject, IFoo { private readonly IFoo target; public void FooCrossDomainProxy(IFoo target) { this.target = target; } public void Bar() => target.Bar(); } 

In a more complicated case, this proxy can be assigned to adapt the interface to cross-domain interaction. For example, since calls between domains are slow, it makes sense to reduce their number by combining methods:

 class FooCrossDomainProxy: MarshalByRefObject { private readonly IFoo target; public void FooCrossDomainProxy(IFoo target) { this.target = target; } public bool TryBar() { if (!target.CanBar) return false; target.Bar(); return true; } } 
  • The comments gave an example with plugins. It turns out that for plug-ins you need to put a restriction, mandatory inheritance from MarshaByRefObject? - iluxa1810
  • Not. That you must implement a cross-domain proxy for all of your extension interfaces. - Pavel Mayorov