3

I am building a conditional formatting feature, where the user can enter an expression like

someFieldValue == "someValue"

And we apply formatting based on the result of that expression. The quickest way to accomplish this (with a full-featured expression syntax) seems to be to with CSharpCodeProvider.CompileAssemblyFromSource.

Because the expression is entered by the user, this is a huge security hole (for example the user could enter the expression, someFieldValue == Process.Start("shutdown","/s /t 0")).

The question: IF this were for a production system, how could I ensure that the expression entered does not cause problems? Right now it's just an internal tool but in case we expose it to a production system I want to be prepared and not go down a path (C# CodeDom) only to scrap it later.

Some things that would be considered unsafe:

  • Exiting the application
  • Accessing / modifying local resources like files / registry / system settings
  • Modifying objects in memory
  • Crashing the calling process
  • Launching applications
  • ...

Since it's unreasonable to enumerate all the things you can't do, my feeling is that the solution will involve modifying the user-entered expression so it operates on a proxy object that exposes all the capabilities we are willing to expose to the expression. That would imply not allowing arbitrary function calls in the expression. It also means the expression is no longer standard C# code, and in the end it may be more practical to use a different language syntax altogether for this.

The benefits of being able to use C# are HUGE, because we want to allow "plugins" in C# which can be used in the expressions, and it allows a nice seamless integration with existing code. I accept that one solution is to use a scripting language like javascript, but I would like to make sure we must rule out C# first.

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • Maybe using DynamicExpression to allow a set number of operators/expressions. Or more generally, parse the expression string into an expression tree, where you have a list of allowed nodes. – George Duckett Jan 18 '12 at 11:04
  • You are describing a user attacking *themselves*. Users are allowed to attack themselves. Why is this a security hole? – Eric Lippert Jan 18 '12 at 15:14
  • 1
    Web server. The expressions are entered by clients, but with unrestricted access they could cause havoc on the server. For the moment it's just for internal use so it's not a problem, but in production it would be unacceptable. AppDomain solved the problem though. – tenfour Jan 18 '12 at 15:22
  • 1
    Makes sense. You might consider mentioning details like that when you ask security questions! – Eric Lippert Jan 18 '12 at 15:23

1 Answers1

3

I think you should have a look at this;

Assembly.CreateInstance and security

The recommended approach for this is to execute the suspect code in a sandboxed appdomain. Several reasons are given at http://blogs.msdn.com/b/shawnfa/archive/2006/04/19/579066.aspx, and an even more important one is that most of the other potential approaches are deprecated as of .NET 4.0.

Community
  • 1
  • 1
AnthonyBlake
  • 2,334
  • 1
  • 25
  • 39
  • 2
    Thank you - I have now implemented this, and indeed AppDomains are exactly what I'm looking for. For those who are interested, a good resource is [this article](http://msdn.microsoft.com/en-us/library/bb763046.aspx) – tenfour Jan 18 '12 at 13:51