nreco / lambdaparser

Runtime parser for string expressions (formulas, method calls). Builds dynamic LINQ expression tree and compiles it to lambda delegate.
http://www.nrecosite.com/
MIT License
309 stars 55 forks source link

Security? #29

Open Apskaita5 opened 4 years ago

Apskaita5 commented 4 years ago

I can see from the examples that the expression can invoke native methods, like ToUpper. Is that safe to use when expressions are entered by a web application users? Actually I'm looking for a simple math parser with conditional support ("if...else"), but all the solutions I found (yet) are using code generation in one way or another, which in my case is both overkill and security risk.

VitaliyMF commented 4 years ago

In expression it is possible to call any public methods that are available in objects passed in the context. It is not possible to call static (or extension) methods in any way.

This means that you can control what is possible to call by providing evaluation context.

Apskaita5 commented 4 years ago

User will not be able to declare a variable (e.g. File) within an expression?

VitaliyMF commented 4 years ago

No, it is not possible to call smth like File.ReadAllText() directly.

Apskaita5 commented 4 years ago

I mean smth like "(new FileInfo("whatever")).DoWhatever()"?

VitaliyMF commented 4 years ago

In expression user cannot create .NET object directly. "new" works for creation of an array or Dictionary. If you need to give a possibility to create some objects this should be exposed explicitly with 'factory' method that is passed as a delegate to the evaluation context (like CreateMyObject() ).

Apskaita5 commented 4 years ago

Ok, last question :) Is it possible to implement (custom?) variadic function, e.g. iff( cond-1, expr-1; ... ; cond-n, expr-n ) ? I know I can use "?" but that's a bit hard/inconvenient for users non programmers. Thx for your patience.

VitaliyMF commented 4 years ago

Sure you can include any 'helper' functions into evaluation context. Smth like this:

varContext["IFF"] = (Func<bool, object, object,object>)((cnd, trueVal, falseVal) => {
  return cnd ? trueVal : falseVal;
});
Console.WriteLine(lambdaParser.Eval("IFF( 10 > 5,  \"Yes\", \"No\" )", varContext));