Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing untrusted plugins in .NET web application

I'd like to develop an application that accepts plugins from the user community, similar to how Chrome or Firefox does. This would be a web application, so each "instance" of the application for individual users would run different plugins (plugins would be loaded as singleton instances, but would be "active" only for certain users). I'm planning on implementing the application in .NET, and trying to come up with an architecture for the plugin model.

Here are my desired attributes:

  • Plugins are built entirely outside of my core application, as separate assemblies.
  • Plugins run in their own "locked down", low-trust environment. Probably a separate AppDomain.
  • Plugins can only act through an API that I provide. E.g. I will pass them some sort of facade as an interface, and they can only call to that, not call to any other assemblies. I can't have plugins that can arbitrarily take actions on the web server, e.g. affect the file system.
  • A fatal crash in the addin cannot affect the stability of the core application.

It seems like System.AddIn is my best bet, but I am unclear on how I can force the loaded addins to only work through the API that I provide, and not load any other assemblies. Does System.AddIn provide that functionality? Also, can System.AddIn be used with ASP.NET / IIS?

What other options do I have besides System.Addin?

like image 686
RationalGeek Avatar asked Apr 01 '13 12:04

RationalGeek


2 Answers

It looks like your primary concern is isolation (for security as well as for robustness).

As such your best option here is to activate your addin in a separate AppDomain. Within this domain you can control what assemblies you would allow to be loaded (see AppDomainSetup class).

Your main code will be also protected from anything untoward happening inside a plugin: All the plugin methods will have to work with are copies of the core objects (unless objects you pass over are inherited from MarshalByRefObject, in which case all bets are off). The exceptions in the addin methods can be handled by wrapping all calls in try except, or through AppDomain's UnhandledExcption event.

Keep in mind that there is a performance penalty for crossing the AppDomain boundaries. The call is essentially a remoting call.

Another potential problem is how do you plan to manage the AppDomains. I never tried to create more than a few AppDomains in a process, but I would expect trouble here. Combining Addins for multiple users in a single domain wold challenge the protection you are trying to build into this

In response to @RationalGeek question - UnhandledException event allows to do that - sort of. You can subscribe to this event in both your core domain as well as the plugin domain, but there is a lot of uncertainties in doing it this way - see the article I referenced for more details. May be a better option would be to wrap every call to your API in try/except

like image 118
mfeingold Avatar answered Nov 17 '22 00:11

mfeingold


You could try using AppDomains and handle the unhandled exceptions. To avoid appdomain crashes, you will have to handle the AppDomain.UnhandledException

In the above link, note the following statement

Starting with the .NET Framework 4, this event is not raised for exceptions that corrupt the state of the process, such as stack overflows or access violations, unless the event handler is security-critical and has the HandleProcessCorruptedStateExceptionsAttribute attribute.

So you may need to explicitly handle some configuration.

I have read a lot of issues claiming that when unhandled exceptions occur on different threads in the child domain, the bubble up and bring down the parent domain. If so, then loading all the plugins into a separate process with a appdomain per plugin or loading the plugins into separate process may be advisable.

I also came across the following question on SO that I believe you would find very helpful

  • Looking for a practical approach to sand boxing .NET plugins
like image 1
Patrick D'Souza Avatar answered Nov 17 '22 00:11

Patrick D'Souza