469,931 Members | 2,734 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,931 developers. It's quick & easy.

CodeDom: Runtime code evaluation and system security

balabaster
797 Expert 512MB
I don't know if anyone's got any clue about this, but I have the following expression evaluator which makes use of the CodeDom to evaluate a VB.NET expression at runtime.

This gives the system administrator the ability to add ad-hoc expressions onto the system, and when users execute these expressions, they are prompted for data for the arguments.

Expand|Select|Wrap|Line Numbers
  1. Function Evaluate(ByVal Expression As String, ByVal Args() As Object) As Double
  2.  
  3.         If Expression.Length > 0 Then
  4.  
  5.             'Replace each parameter in the calculation expression with the correct values
  6.             Dim MatchStr = "{(\d+)}"
  7.             Dim oMatches = Regex.Matches(Expression, MatchStr)
  8.             Dim DistinctCount = (From m In oMatches _
  9.                                  Select m.Value).Distinct.Count
  10.             If DistinctCount = Args.Length Then
  11.                 For i = 0 To Args.Length - 1
  12.                     Expression = Expression.Replace("{" & i & "}", Args(i))
  13.                 Next
  14.             Else
  15.                 Console.WriteLine("Invalid number of parameters passed")
  16.             End If
  17.  
  18.             Dim FuncName As String = "Eval" & Guid.NewGuid.ToString("N")
  19.             Dim FuncString As String = "Imports System.Math" & vbCrLf & _
  20.                                        "Namespace EvaluatorLibrary" & vbCrLf & _
  21.                                        "  Class Evaluators" & vbCrLf & _
  22.                                        "    Public Shared Function " & FuncName & "() As Double" & vbCrLf & _
  23.                                        "      " & Expression & vbCrLf & _
  24.                                        "    End Function" & vbCrLf & _
  25.                                        "  End Class" & vbCrLf & _
  26.                                        "End Namespace"
  27.  
  28.             'Tell the compiler what language was used
  29.             Dim CodeProvider As CodeDomProvider = CodeDomProvider.CreateProvider("VB")
  30.  
  31.             'Set up our compiler options...
  32.             Dim CompilerOptions As New CompilerParameters()
  33.             With CompilerOptions
  34.                 .ReferencedAssemblies.Add("System.dll")
  35.                 .GenerateInMemory = True
  36.                 .TreatWarningsAsErrors = True
  37.             End With
  38.  
  39.             'Compile the code that is to be evaluated
  40.             Dim Results As CompilerResults = _
  41.                 CodeProvider.CompileAssemblyFromSource(CompilerOptions, FuncString)
  42.  
  43.             'Check there were no errors...
  44.             If Results.Errors.Count > 0 Then
  45.             Else
  46.                 'Run the code and return the value...
  47.                 Dim dynamicType As Type = Results.CompiledAssembly.GetType("EvaluatorLibrary.Evaluators")
  48.                 Dim methodInfo As MethodInfo = dynamicType.GetMethod(FuncName)
  49.                 Return methodInfo.Invoke(Nothing, Nothing)
  50.             End If
  51.  
  52.         Else
  53.             Return 0
  54.  
  55.         End If
  56.  
  57.     End Function
This can be called using something like:
Expand|Select|Wrap|Line Numbers
  1. Dim Expr As String = "  If ({0} < 20000) Then" & vbCrLf & _
  2.                      "    Return MAX(15, MIN(75,0.12*{0}))" & vbCrLf & _
  3.                      "  Else" & vbCrLf & _
  4.                      "    Return MAX(75,0.05*{0})" & vbCrLf & _
  5.                      "  End If"
  6. Dim Args() As Object = New Object() {2300}
  7. Dim dblOut = Evaluate(Expr, Args)
  8. Console.WriteLine(dblOut)
  9. Console.ReadLine()
The expression could equally be extracted from the text of a RichTextBox.

Now, I'm looking at running this code on a web server, and as such, security is going to be an issue (not that I want to come across as not trusting the system administrators, but you never know what the future brings). While this code may be running in isolated memory space, it's not prevented from reading and writing to the system. Is there any way to lock it down to prevent someone from adding potentially insecure references?
Sep 5 '08 #1
0 1235

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

reply views Thread by Ron Bullman | last post: by
1 post views Thread by fred_mumble | last post: by
1 post views Thread by John Livermore | last post: by
reply views Thread by Michael Jenck | last post: by
1 post views Thread by =?Utf-8?B?QU1lcmNlcg==?= | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.