我目前正在尝试在PHP中创建一个简单的模板引擎。我主要关心的是安全性,但是模板教程却没有。可以说我有一个数据库表,其中包含用户名及其描述。用户可以在此处键入任何想要的内容。
我的猜测是使用htmlspecialchars()函数来防止javascript和html注入。但是“模板代码注入”呢?如果我的模板规则是将[@key]替换为“值”,则用户可以更新其描述,该描述会干扰我的模板处理程序。使用set方法时,是否应该将“ [”,“ @”,“]”视为特殊字符并用其ascii代码替换?
template.php:
class Template {
protected $file;
protected $values = array();
public function __construct($file) {
$this->file = $file;
}
public function set($key, $value) {
$this->values[$key] = $value;
}
public function output() {
if (!file_exists($this->file)) {
return "Error loading template file ($this->file).";
}
$output = file_get_contents($this->file);
foreach ($this->values as $key => $value) {
$tagToReplace = "[@$key]";
$output = str_replace($tagToReplace, $value, $output);
}
return $output;
}
}
example.tpl:
用户名:[@name]
关于我:[@info]
index.php:
include 'template.php';
$page = new Template('example.tpl');
$page->set('info', '[@name][@name][@name]I just injected some code.');
$page->set('name', 'Tom');
echo $page->output();
这将显示:
用户名:Tom
关于我:TomTomTom我刚刚注入了一些代码。
我使用的代码基于:
http://www.broculos.net/2008/03/how-to-make-simple-html-template-engine.html
将功能更改为在不变的模板中仅搜索一次已知键:
public function output() {
if (!file_exists($this->file)) {
return "Error loading template file ($this->file).";
}
$output = file_get_contents($this->file);
$keys = array_keys($this->values);
$pattern = '$\[@(' . implode('|', array_map('preg_quote', $keys)) . ')\]$';
$output = preg_replace_callback($pattern, function($match) {
return $this->values[$match[1]];
}, $output);
return $output;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句