对于站点,内容创建者以cronjob(perl)解析到mysql数据库的格式维护html列表。php将数据拉入分页索引。
<li>Lorem ipsum dolor sit amet<br>
<a href="../path/to/file.php">Lorem ipsum dolor sit amet</a><br>
consectetuer adipiscing elit</li>
(perl提取文本和url,并将它们作为header、url、linktext和footer存储在数据库中。)
有时会在文本中插入用户函数调用,如下所示:
<li>Lorem ipsum <?php age(1234) ?> dolor sit amet<br>
<a href="../path/to/file.php">Lorem ipsum dolor sit amet</a><br>
consectetuer adipiscing elit</li>
查询返回第一行($header)的字符串:
'Lorem ipsum <?php age(1234) ?> dolor sit amet'
当然,在拉入查询时不会执行此操作。它也不会出现在固定的位置,因此无法解析为单独的字段。
我读了一些关于使用 eval
在这里,考虑到只有内容创作者在家里编辑列表,它应该是足够安全的。如果邪恶的代码被注入到列表或数据库中,我们会遇到比外部插入到表单中的未初始化代码更大的问题。
我的另一个想法是 preg_replace_callback()
. 然而,一些人提出了这样的建议,从本质上说,它与 eval
,尽管我认为正则表达式应该/可以锁定这一点。另外,我不知道它如何执行任意代码,除非将其作为参数值传递给用户函数。
更好的方法是什么?还是有其他更安全的方法(php 7.2、mysql 5.6版)
短暂性脑缺血发作
编辑
我已经使用回调实现了下面的代码,没有 eval
. 仅适用于少数允许的函数,顺便说一下,所有这些函数都只需要一个数值参数,它似乎被完全锁定了。
if (stristr($header, '<?php ') !== FALSE) {
$header = preg_replace_callback(
'/<\?php (?P<php>(?P<func>(function|whitelist))?\((?P<value>\d+)\)) \?\>/i',
function($matches) {
// print_r($matches);
ob_start(); // functions print, not return
// $matches['php']; // does not work
$matches['func']($matches['value']); // works
// call_user_func($matches[1], $matches[2]); // unnecessary detour
// $out = ob_get_clean(); // ditto
// return $out;
return ob_get_clean();
},
$header
);
}
谢谢你的帮助。
暂无答案!
目前还没有任何答案,快来回答吧!