1

In a situation where you wanted to allow users to define search filters, would it be possible to take a string, dynamically compile that, and execute it in a sandbox which wouldn't allow it access to anything outside of the sandbox.

Consider that my app has a list of objects. I want to allow a power user to write C# in the interface (so, literally in a textarea inside of a browser) and receive that as a string (as a POST).

Something like this:

var foo = "bar";
return objects.Where(o => o.Property == foo);

Again, I would get this as a string (this is not compiled out of Visual Studio). Then I could dynamically compile that into a temporary helper class (this is the easy part -- I've done this).

What I haven't done is execute that in such a way that I know it's not going negatively affect resources outside of itself. Because, let's face it, they could write this:

File.Delete(Path.Combine(AppDomain.Current.BaseDirectory), "web.config"));

That would clearly be bad, but since they're writing C# as a string and having it dynamically compiled, I'm not sure there's much I can do about it.

What I want to do it compile and execute this string in such a way that it only has accesses to the resources I give it. It will be compiled to something like this:

public static class Temp : IDynamicFilter
{
  public static List<MyClass> Filter(List<MyClass> objects)
  {
    [their string goes here]
  }
}

Then Filter will be called (from IDynamicFilter).

I realize that this clearly might be a bad idea. And some of this is hypothetical -- I'm quite interested in the theory of running sandboxed code-within-code, beyond the specifics of this example.

Deane
  • 8,269
  • 12
  • 58
  • 108
  • This is clearly a bad approach. If you really want to do this you should run the compiled code under an user account with limited privileges, see for example http://stackoverflow.com/questions/6413900/launch-a-process-under-another-users-credentials – Alex Oct 16 '15 at 13:22
  • Don't really have an answer here, bu you may want to have a look at Roslyn: http://www.filipekberg.se/2011/12/08/hosted-execution-of-smaller-code-snippets-with-roslyn/ – Paddy Oct 16 '15 at 13:22
  • 2
    Did you google "sandbox c# code"? First result: https://msdn.microsoft.com/en-us/library/bb763046(v=vs.110).aspx – Ron Beyer Oct 16 '15 at 13:25
  • 2
    Roslyn already supports scripting, even in preview form. It's better to create a proper search language though, parse it to a syntax tree and then execute it. As for what can be called - that *is* up to you. In both cases, it's your code that provides callable interfaces to the script – Panagiotis Kanavos Oct 16 '15 at 13:25
  • why dont you just outlaw certain keywords: `delete`, `remove`... – maraaaaaaaa Oct 16 '15 at 13:31

1 Answers1

1

.NET is kind of designed for this. It has a full support for sandboxing, with complicated permissions system to give you a control over the safety. The basic idea is that you run the C# code in a separate AppDomain, which has no permissions at all. This might make it somewhat tricky to interface with your application - careful about that.

However, the code isn't running in complete isolation. Blocking File.Delete is easy. Blocking reflection is easy (in fact, reflection is only possible in a full trusted environment, for obvious reasons - along with unsafe code). It might be possible to use it to interact with other AppDomains in dangerous ways - I really am not sure. It might also be tricky to pick the exact set of permissions to give you the capabilities you want to expose, without exposing anything dangerous - you'll probably need to make your own sandbox methods that give you fairly strict ways to handle the work needed (this allows you to e.g. allow certain file operations through your methods without allowing any file operations to the sandboxed application).

Is this safe enough for you? Hard to say. Do the users even have an incentive to use this maliciously, though? If they do, you probably want to use a language of your own, instead of using C# - something very specific. If they don't, you don't really have to bother much - even handling the code permissions might be an overkill (it is hard to use - which might translate to time wasted).

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • Do AppDomains get created with _any_ permissions, or do you have to explicitly grant all of them? If I just called `AppDomain.CreateDomain("name")`, can it be assumed that this is as neutered as an AppDomain can get? – Deane Oct 16 '15 at 13:59
  • @Deane No, the default is actually "the same setup as my domain". It's really one of those things where you want to read through the documentation, and find an article or two about how to use this properly. – Luaan Oct 16 '15 at 14:05