开发者

How can I safely use eval in php?

I know some people may just respond "never" as long as there's user input. But supp开发者_Go百科ose I have something like this:

$version = $_REQUEST['version'];
$test = 'return $version > 3;';
$success = eval($test);

This is obviously a simplified case, but is there anything that a user can input as version to get this to do something malicious? If I restrict the type of strings that $test can take on to comparing the value of certain variables to other variables, is there any way anybody can see to exploit that?

Edit

I've tried running the following script on the server and nothing happens:

<?php
  $version = "exec('mkdir test') + 4";
  $teststr = '$version > 3;';
  $result = eval('return ' . $teststr);
  var_dump($result);
?>

all I get is bool(false). No new directory is created. If I have a line that actually calls exec('mkdir test') before that, it actually does create the directory. It seems to be working correctly, in that it's just comparing a string converted to a number to another number and finding out the result is false.


Ohhhh boy!

$version = "exec('rm-rf/...') + 4"; // Return 4 so the return value is "true" 
                                    // after all, we're gentlemen!
$test = "return $version > 3"; 
eval($test);

:)

You would have to do at least a filter_var() or is_numeric() on the input value in this case.

By the way, the way you use eval (assigning its result to $success) doesn't work in PHP. You would have to put the assignment into the eval()ed string.


If you do this. Only accept ints.

If you must accept strings, don't.

If you still think you must. Don't!

And lastly, if you still, after that, think you need strings. JUST DON'T!


yes, anything. I would use $version = (int)$_REQUEST['version']; to validate the data.


You need to be more precise with your definitions of "malicious" or "safe". Consider for example

exec("rm -rf /");

echo "enlarge your rolex!";

while(true) echo "*";

all three snippets are "malicious" from the common sense point of view, however technically they are totally different. Protection techniques that may apply to #1, won't work with other two and vice versa.


The way to make this safe would be to ensure that $version is a number BEFORE you try to eval.


Use this code to remove everything except numbers (0-9): preg_replace('/[^0-9]+/', '', $version);

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜