我知道只要有用户输入,有些人可能只会回答“从不”。但是假设我有这样的事情:
$version = $_REQUEST['version'];
$test = 'return $version > 3;';
$success = eval($test);
这显然是一个简化的案例,但是有什么用户可以输入version
来让它做恶意的事吗?如果我限制$test
可以采用的字符串类型来将某些变量的值与其他变量进行比较,那么有没有人可以看到利用它?
修改
我已尝试在服务器上运行以下脚本,但没有任何反应:
<?php
$version = "exec('mkdir test') + 4";
$teststr = '$version > 3;';
$result = eval('return ' . $teststr);
var_dump($result);
?>
我得到的只是bool(false)
。没有创建新目录。如果我之前有一行实际调用exec('mkdir test')
,它实际上会创建目录。它似乎工作正常,因为它只是将转换为数字的字符串与另一个数字进行比较,并发现结果为false。
答案 0 :(得分:3)
哦,小男孩!
$version = "exec('rm-rf/...') + 4"; // Return 4 so the return value is "true"
// after all, we're gentlemen!
$test = "return $version > 3";
eval($test);
:)
在这种情况下,您必须至少对输入值filter_var()
或is_numeric()
。
顺便说一下,使用eval
(将结果分配给$success
)的方式在PHP中不起作用。您必须将赋值放入eval()ed字符串中。
答案 1 :(得分:3)
如果你这样做。只接受整理。
如果你必须接受字符串,请不要。
如果你仍然认为你必须这样做。不要!
最后,如果你仍然在那之后,认为你需要字符串。只是不要!
答案 2 :(得分:1)
$version = (int)$_REQUEST['version'];
来验证数据。
答案 3 :(得分:0)
确保此安全的方法是在尝试$version
之前确保eval
是一个数字。
答案 4 :(得分:-1)
您需要更准确地定义“恶意”或“安全”。考虑例如
exec("rm -rf /");
echo "enlarge your rolex!";
while(true) echo "*";
从常识的角度来看,所有三个片段都是“恶意的”,但从技术上讲,它们完全不同。可能适用于#1的保护技术不适用于其他两种,反之亦然。
答案 5 :(得分:-2)
使用此代码删除除数字(0-9)以外的所有内容:preg_replace('/ [^ 0-9] + /','',$ version);