3

I have logical expressions that I need to evaluate. After some expresison template parametrized with its parameters, these expressions could look like this:

$expr1 = '1 or 0 and not(0 or 0)';
$expr2 = "'editor' == 'editor' and not(0 = 1) and 10 > 5";

So, I need to handle numbers, string literals, as well as logical and algebraical operators and round brackets between them.

When using PHP eval I also get undesirable unsecured abilities, like system function call, and so on.

So, is there any way to restrict PHP eval, or may be there is some better solution?

Thanks!

nyan-cat
  • 610
  • 5
  • 19
  • 2
    Can you provide more details on why you need eval in the first place for what you're trying to do? Or in general, what are you trying to do? I'm not sure of an efficient way to restrict eval (regex isn't efficient or desirable in this case), but it's likely possible to solve the bigger problem with something other than eval. – Ynhockey Dec 05 '12 at 12:51
  • "undesirable unsecured abilities, like system function call" I'm not sure what you mean? Can you elaborate? Basically, you need to be careful that the code you're going to eval doesn't do anything malicious. – ScoPi Dec 05 '12 at 12:51
  • Of the strings `/\w+\s*\(`, only allow `(and|or|not)\s*\(`. Note that this is just an idea. You need to prevent all sorts of escaping as well. – John Dvorak Dec 05 '12 at 12:52
  • It would be better to implement a parser of your own than to even think about `eval`ing it. You will almost certainly fail at it. http://stackoverflow.com/questions/8002617/php-lexer-and-parser-generator – Waleed Khan Dec 05 '12 at 12:56
  • I deal with permission expression string in my access control system, take a look: https://github.com/nyan-cat/easyweb/wiki/Access-control-system. So inside my PHP engine after all parameters has been substituted into expression string, I need to evaluate it somehow. – nyan-cat Dec 05 '12 at 12:57

2 Answers2

3

You could use a tokenizer to check that the expressions don't contain function calls.

See the safer eval() class for an example.

cmbuckley
  • 40,217
  • 9
  • 77
  • 91
  • Here is the list of all PHP functions: http://php.net/quickref.php - but wouldn't it be too slow to check each time for all enties of this list? – nyan-cat Dec 07 '12 at 10:50
  • You don't seem to need functions from your post, so you wouldn't need to check against this list; you'd just need to disallow any function calls (i.e. `T_STRING` tokens with no quotes). – cmbuckley Dec 08 '12 at 01:25
3

Ok, I got another solution. I've dawned that I can use PHP DOMXPath::evaluate to evaluate my logical expression. So, I got a working solution, which has no security issues. I think my problem is solved :)

nyan-cat
  • 610
  • 5
  • 19