Verify (re-run) client side math calculations on the server

44 Views Asked by At

Our users can run mathematical calculations based on form fields. To evaluate the calculation, I'm using expr-eval as expression evaluator for javascript (client side) (https://github.com/silentmatt/expr-eval).

An example expression is: x = 10; 2 + (4*x)

For security reasons, we should verify the result of the calculation on server side as well. Therefore, I want to re-run the calculation with the incoming data on the server using PHP, after the form has been submitted.

How would I do that? expr-eval comes with a lot of possibilities like ternary conditions, variable declarations and so on. As there is no equivalent library for PHP, what would be the way of running such a verification? I could setup a Node.js server running the expr-eval, but would an additional request really be the best practice here?

1

There are 1 best solutions below

0
symcbean On

Eval will do most of what you need, but:

  • it does not handle variables in the way you need
  • if you allow anything which is not an arithmentic operator or a number to be 'eval'ed then the code is exploitable.

i.e. you're going to need to define your syntax very strictly, implement your own parser then hand off the final expression to eval.

Something like....

function safer_eval($expr)
{
  $facts=array();
  $result=false;
  $lines=explode(";", $expr);
  foreach ($lines as $l) {
    $p=explode('=', $l);
    switch (count($p)) {
      case 2:
         $facts[$p[0]]=evalexpr($p[1], $facts);
         break;
      case 1:
         return evalexpr($p[0], $facts);
         break;
      default:
         break 2;
     }
  }
  return false;
}

function evalexpr($expr, $facts) 
{
   $expr=str_replace(array_keys($facts), $facts, $expr);
   if (!preg_match("/^([0-9+-/*\.\(\)\^ )+$/", $expr)) {
      return false;
   }
   return eval($expr);
}