编辑:周围的好点,专用的模板语言显然是要走的路.谢谢!
我写了这个快速课程来通过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): ?> 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这样的模板语言更标准的路线……
解决方法:
当然..
$template_code = '= `rm -rf *`; ?>';
编辑:
不能马上想到任何其他事情.但是如果在同一个Template实例上多次调用渲染,你应该知道你的范围受到了损害.
例如,如果你渲染(‘ allowed_methods [] =“eval”;?>’)..那么Template的实例将eval作为下一个渲染的可接受函数.
标签:php,templates
来源: https://codeday.me/bug/20190715/1463636.html