嗨,这是我的情况:我必须让我的客户输入PHP代码,但只有字符串函数,日期函数等安全函数。所以我需要危险的PHP函数列表,在保存到PHP之前使用字符串替换删除它们文件。有什么建议吗?
答案 0 :(得分:7)
算了。在php中无法实现可靠的功能白名单。例如:
$x = 'e' . str_replace('y', 'x', 'yec');
...lots of code...
$x('format c:');
现实选项
答案 1 :(得分:2)
据我所知,你只能使用黑名单方法:
当然,您必须考虑维护由所有可能的扩展定义的所有内置函数的更新列表的可行性。
我能想到的另一种可能性是写一个简单的标记化器:
http://es2.php.net/manual/en/function.token-get-all.php
然后,您可以检查用于白名单的功能。
更新:我的错误印象是token_get_all()
会识别函数调用,但实际上并没有。他们都是T_STRING
。
答案 2 :(得分:2)
最安全且易于维护的选项是在php中编写专用的“迷你语言”。你可以把它作为php的一个子集,或者使它看起来像Excel公式,甚至可以创建自己的公式。通过这种方式,您可以完全控制正在发生的事情。
//
只是为了好玩,这里有一个小Lisp给你
function lisp($x) {
if(is_string($x)) {
$re = '~\(([^()]*)\)~';
while(preg_match($re, $x))
$x = preg_replace_callback($re, 'lisp', $x);
return trim($x);
}
$x = preg_split('~\s+~', $x[1]);
$e = array_shift($x);
if(!$x)
return is_numeric($e) ? floatval($e) : $e;
switch($e) {
case '+': return lisp($x[0]) + lisp($x[1]);
case '-': return lisp($x[0]) - lisp($x[1]);
case '*': return lisp($x[0]) * lisp($x[1]);
case '/': return lisp($x[0]) / lisp($x[1]);
case 'concat': return lisp($x[0]) . lisp($x[1]);
}
return function_exists($e) ?
call_user_func_array($e, array_map('lisp', $x)) : '';
}
$input = '
(strtolower
(concat
(strrev olleh)
(+ 22 20)))';
echo lisp($input); // hello42
))
答案 3 :(得分:1)
为用户提供输入PHP代码的可能性非常危险。在实现此之前考虑所有其他选项。某种PHP代码构建器。灵感来自查询构建器。
如果您决定允许客户端使用PHP代码,最好使用白名单。 您应该使用正则表达式从发布的代码中提取这些函数。
答案 4 :(得分:1)