Using PHP as template language

Posted by Kunal on Stack Overflow See other posts from Stack Overflow or by Kunal
Published on 2010-05-05T04:24:09Z Indexed on 2010/05/05 4:28 UTC
Read the original article Hit count: 366

Filed under:
|

I wrote up this quick class to do templating via PHP -- I was wondering if this is easily exploitable if I were ever to open up templating to users (not the immediate plan, but thinking down the road).

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;     
}

}

Example usage:

$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);

The idea here is that I'd store the templates (PHP code) in the database, and then run it through the class which uses regular expressions to only allow permitted methods (if, for, etc.). Anyone see an obvious way to exploit this and run arbitrary PHP? If so, I'll probably go the more standard route of a templating language such as Smarty...

© Stack Overflow or respective owner

Related posts about php

Related posts about templates