【发布时间】:2010-05-05 04:24:09
【问题描述】:
编辑: 很重要的一点,专用的模板语言显然是要走的路。谢谢!
我编写了这个快速课程来通过 PHP 进行模板化——我想知道如果我曾经向用户开放模板,这是否很容易被利用(不是近期计划,而是考虑未来)。
class Template {
private $allowed_methods = array(
'if',
'switch',
'foreach',
'for',
'while'
);
private function secure_code($template_code) {
$php_section_pattern = '/\<\?(.*?)\?\>/';
$php_method_pattern = '/([a-zA-Z0-9_]+)[\s]*\(/';
preg_match_all($php_section_pattern, $template_code, $matches);
foreach (array_unique($matches[1]) as $index => $code_chunk) {
preg_match_all($php_method_pattern, $code_chunk, $sub_matches);
$code_allowed = true;
foreach ($sub_matches[1] as $method_name) {
if (!in_array($method_name, $this->allowed_methods)) {
$code_allowed = false;
break;
}
}
if (!$code_allowed) {
$template_code = str_replace($matches[0][$index], '', $template_code);
}
}
return $template_code;
}
public function render($template_code, $params) {
extract($params);
ob_start();
eval('?>'.$this->secure_code($template_code).'<?php ');
$result = ob_get_contents();
ob_end_clean();
return $result;
}
}
示例用法:
$template_code = '<?= $title ?><? foreach ($photos as $photo): ?><img src="<?= $photo ?>"><? endforeach ?>';
$params = array('title' => 'My Title', 'photos' => array('img1.jpg', 'img2.jpg'));
$template = new Template;
echo $template->render($template_code, $params);
这里的想法是我将模板(PHP 代码)存储在数据库中,然后通过使用正则表达式的类运行它,以仅允许允许的方法(if、for 等)。任何人都看到了一种明显的方法来利用它并运行任意 PHP?如果是这样,我可能会采用更标准的模板语言,例如 Smarty...
【问题讨论】:
-
你真的不应该这样做。有一千种制造麻烦的方法,你将不可避免地错过。试图阻止它们中的每一个都会使模板变得无用。
-
明白了,也明白了。这实际上仅供内部使用,但我想知道我自己的教化的利用可能性。
-
请注意,Smarty 也不完全安全 (smarty.net/manual/en/language.function.php.php)。
-
@tadamson:嗯,我认为有办法禁用该标签...也许不是。
-
如果您得到了答案,请点击旁边的绿色大勾号接受。谢谢,祝你好运。 :)