Reputation: 7153
For a complex project I'm working on, I want administrators to be allowed to attach conditions to events using boolean expressions.
Example:
if (1 > 2 || (1 == 1 && 3 > 2)) [...]
The above would return TRUE.
eval()
seems like an easy solution, but I am well aware of the security risks it presents. Does PHP provide a way to evaluate expressions like the above without actually evaluating other arbitrary PHP code? Options would be something that only evaluates mathematical expressions, or perhaps an eval()
sanitizer that accepts a whitelist of functions.
Thanks for your help!
Upvotes: 1
Views: 517
Reputation: 434
The best thing is as your suggestion "sanitizer", by using token_get_all
below (incomplete) snippet so you might get the idea
function evalExpression ($expression)
{
$code = "return $expression;";
$token = token_get_all($code,TOKEN_PARSE);
# return
unset($token[1]);
foreach ($token as $key=>$value) {
if(is_array($value)) {
# white list token
$allow = [T_WHITESPACE,T_LNUMBER,/* add more token*/];
# remove white list token
if(in_array($value[0],$allow,true)) {
unset($token[$key]);
}
} else {
# white list string
$allow = [';','>'/* add more element*/];
# remove white list string
if(in_array($value,$allow,true)) {
unset($token[$key]);
}
}
}
# if token contain only white listed, $token should empty
if(!$token) {
return eval($code);
} else {
throw new \InvalidArgumentException('err');
}
};
# return bool
var_dump(evalExpression('2 > 1'));
# should error
var_dump(evalExpression('function(){}'));
since eval construct are dangerous you should try to inject/test with malicious code, before run into production
Upvotes: 1