Friday, May 6, 2011

Using Compile Assembly From Source to evaluate math equations in C#

I am considering parsing simple math equations by compiling from source at runtime. I have heard that there are security considerations that I should be aware of before using this approach, but I can’t find any info on this.

Thanks

C# .net 2.0, winforms

From stackoverflow
  • The problem with this approach is that a user could enter any code they wanted (unless you sanitize it). They could put in code to erase all your files. If this is running on a server, do not do this. Also, even on a desktop, running a compiler just to evaluate an equation is really slow. Make a grammar for your equations with a tool like ANTLR, and embed the parser into your program.

  • Compiling is a relatively safe operation. It seems like it would only be an issue if there was an exploitable buffer overrun in the compiler. Running the resulting code is certainly a security risk though. Unless you are careful to sanitize the input you could be opening up a rather large security hole in a server application.

    I'm curious why you are taking this approach. Simple math equations have a fairly strict grammar and are very easy to parse. I'm sure there are a few free libraries available and if not writing your own isn't a huge undertaking. This would probably be a lot faster than shelling out to a compiler in order to validate a math expression's syntax.

    Brad : I have just started trying to determine which approach will fit the best. I am not decided on any direction . I had just heard of using this method and I thought it was intriguing.
    Marc Gravell : For the OP's benefit - consider the well-known math functions File.Delete, Process.Start, etc ;-p
    Brad : I see what you mean
  • Some time ago I stumbled upon a clever way to do this : take advantage of the eval function of JScript. You can create a simple JScript class :

      class JsMath
      {
        static function Eval(MathExpression : String) : double
        {
          return eval(MathExpression);
        };
      }
    

    Compile it like this :

    jsc /target:library JsMath.js

    Now you can just reference the JsMath library and use the JsMath.Eval method.

    Wim Coenen : +1 but you didn't mention the most important point: code run by eval runs in a restricted security context by default, thereby adressing the security concern expressed by the OP. Documentation: http://msdn.microsoft.com/en-us/library/b51a45x6(VS.80).aspx
    Thomas Levesque : indeed, it's also much more secure than dynamic compilation... thanks for the precision ;)
  • If the C# "equations" can be saved and exchanged between users, then there is certainly a security risk. A user could put malicious code in the equation, and have it do bad things on the machines of other users. Or a user could simply be tricked into entering a malicious "equation" (think of the old alt+F4 prank here).

    Fortunately you can safely host untrusted code in a .NET sandbox. The general idea is that you create a separate AppDomain (with the AppDomain.CreateDomain method) that has only minimal permissions, and then load and run the user code there.

    Loading dynamically generated assemblies into a separate AppDomain is a good idea anyway, because it allows you to unload them again.

0 comments:

Post a Comment