0

i am trying to implement a function that you can pass a formula into as well as a array that'll become variables for the formula, but due to the way it works i had to use the eval function, which i know is insecure, so i tried looking into possible dangers and to somewhat protect against the most troublesome dangers i made sure it doesn't eval if input preg matches with exec or " , however is this secure enough or are there other dangers beside exec that i should eliminate? here my code:

<?php
   function calc($formula,$variables){
     extract($variables);
     if(!preg_match('/"/',$formula) && !preg_match('/exec/',$formula)){
       eval("\$formula=$formula;");
       echo $formula;
     }
   }
   calc('0.025*$r-($r-100000)*0.01',@array(r=>1000000));
?>

update: thanks for not downvoting so far, i know this might not be the right place to ask, or not the proper way, but i was kinda struggling on how to ask this anyway

at this moment i discover by your comments eval really isn't safe even with these small "protections" however, i am wondering now on how to else make a function for people to input a formula and variables that might be part of it in order to get the evaluation, so any good tips on that?

  • Where does formula come from? Why aren't you defining your $variables array correctly? – Mark Baker May 09 '17 at 08:51
  • `calc('unlink(\'*\');', []);` will delete your files. – Imanuel May 09 '17 at 08:51
  • [Why not create a proper formula evaluator?](http://stackoverflow.com/questions/12692727/how-to-make-a-calculator-in-php) – Mark Baker May 09 '17 at 08:53
  • the formula is now defined in calc temporarily but will later come out of databse, and later in a apart page-file from user input so that people can type in their formula, then the variables, and it will show them the solution to the formula, thanks for that tip on unlink, that apears to be another security check needed to implement as well as \ , ; and ' to stop even more functions from properly firing, without restricting possible input formula's, okay sot this question belongs to code review? i dunno if i can still put it there but no prob is admin does, and i dunno with the evaluator. – dylan lindelauf May 09 '17 at 09:00
  • 1
    You add another security check, the attacker circumvents it again. Read the answer IMSoP has written and **never use a blacklist for security**. Even if you blacklist all the things IMSoP has mentioned, there will always be others that you haven't thought of yet. – Imanuel May 09 '17 at 09:19

1 Answers1

2

In a word, "no". Your code is not even slightly secure.

eval can run literally any PHP code, so there are an almost unlimited number of ways to do immense damage; off the top of my head:

  • using unlink to delete files from your server
  • reading from /etc/passwd, or from your source code
  • accessing the full contents of your database, using your own database code
  • uploading any of the above to the attacker's server, using curl_exec, or FTP, or SOAP
  • using you as a spam relay with the mail() function
  • using system, which is very similar to exec
  • using a nested eval inside the string to evade your blacklist (e.g. eval('ex'+'ec(\'somecommand\')')

The moral of the lesson is never use a blacklist for security. If your formulas are sufficiently simple, you might be able to define a very careful whitelist, in the form of a pattern that all formulas must meet. You might still be open to creative attacks, though, and are probably better off parsing the formula fully and evaluating it without eval.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • okay but how to do that then? cause i searched very hard and was unable to find a solution without eval, especially as the formula's that people would need to be able to be put can be very top-notch using variables, brackets and everything, so what would you suggest for the evaluation of the formula then? – dylan lindelauf May 09 '17 at 09:35
  • @dylan - why not take a look at the formula evaluator that I originally linked for you – Mark Baker May 09 '17 at 09:39
  • i checked it out but the answers are in oop, and i'm kinda unfamiliar with oop so i don't yet understand what's happening and so on, so that would make me unable to change anything if i'd ever need to... – dylan lindelauf May 09 '17 at 09:45
  • @dylanlindelauf If you're not confident that you can write or maintain an expression parser, find a library or tool that does it for you, or limit your spec to what you are confident of doing. There's no magic tool that will give you both complete flexibility and complete security, but there may be languages more appropriate than PHP to evaluate your expression in. I've seen some tools which use sandboxed JS or Lua scripts, for instance, but you'll probably need to do some integration and configuration. – IMSoP May 09 '17 at 10:32