From 6be6bf7b70346fcf69e1453d04980a1eee287a73 Mon Sep 17 00:00:00 2001 From: Uwe Tews Date: Tue, 30 Dec 2014 12:57:43 +0100 Subject: [PATCH] limit the template nesting level by security --- NEW_FEATURES.txt | 9 ++++- change_log.txt | 10 +++-- libs/sysplugins/smarty_internal_template.php | 6 +++ .../smarty_internal_templatebase.php | 6 +++ libs/sysplugins/smarty_security.php | 37 ++++++++++++++++++- 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/NEW_FEATURES.txt b/NEW_FEATURES.txt index 9118bfc1..282f8df5 100644 --- a/NEW_FEATURES.txt +++ b/NEW_FEATURES.txt @@ -13,9 +13,16 @@ Smarty 3.1.22 Security ======== + - disable special $smarty variable - The Smarty_Security class has the new property $disabled_special_smarty_vars. It's an array which can be loaded with the $smarty special variable names like 'template_object', 'template', 'current_dir' and others which will be disabled. - Note: That this security checking is performed at compile time. + Note: That this security check is performed at compile time. + + - limit template nesting - + Property $max_template_nesting of Smarty_Security does set the maximum template nesting level. + The main template is level 1. The nesting level is checked at run time. When the maximum will be exceeded + an Exception will be thrown. The default setting is 0 which does disable this check. + \ No newline at end of file diff --git a/change_log.txt b/change_log.txt index 47f4166e..c07a64e6 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,8 +1,12 @@ - ===== 3.1.22-dev ===== (xx.xx.2014) + ===== 3.1.22-dev ===== (xx.xx.2014) + 29.12.2014 + - new feature security can now limit the template nesting level by property $max_template_nesting + see also NEW_FEATURES.txt (forum 25370) + 29.12.2014 - new feature security can now disable special $smarty variables listed in property $disabled_special_smarty_vars - see also NEW_FEATURES.txt (forum 25370) - + see also NEW_FEATURES.txt (forum 25370) + 27.12.2014 - bugfix clear internal _is_file_cache when plugins_dir was modified diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index 3f1b05c4..ef014721 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -353,6 +353,9 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase public function getInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash, $content_func) { $tpl = $this->setupInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash); + if (isset($this->smarty->security_policy)) { + $this->smarty->security_policy->startTemplate($tpl); + } if ($this->smarty->debugging) { Smarty_Internal_Debug::start_template($tpl); @@ -367,6 +370,9 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase if (!empty($tpl->properties['file_dependency'])) { $this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $tpl->properties['file_dependency']); } + if (isset($this->smarty->security_policy)) { + $this->smarty->security_policy->exitTemplate($tpl); + } return str_replace($tpl->properties['nocache_hash'], $this->properties['nocache_hash'], ob_get_clean()); } diff --git a/libs/sysplugins/smarty_internal_templatebase.php b/libs/sysplugins/smarty_internal_templatebase.php index 260144f1..dff4a73c 100644 --- a/libs/sysplugins/smarty_internal_templatebase.php +++ b/libs/sysplugins/smarty_internal_templatebase.php @@ -50,6 +50,9 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data if ($this->smarty->debugging) { Smarty_Internal_Debug::start_template($_template); } + if (isset($_template->smarty->security_policy)) { + $_template->smarty->security_policy->startTemplate($_template); + } // if called by Smarty object make sure we use current caching status if ($this instanceof Smarty) { $_template->caching = $this->caching; @@ -323,6 +326,9 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data if (isset($this->error_reporting)) { error_reporting($_smarty_old_error_level); } + if (isset($_template->smarty->security_policy)) { + $_template->smarty->security_policy->exitTemplate($_template); + } // display or fetch if ($display) { if ($this->caching && $this->cache_modified_check) { diff --git a/libs/sysplugins/smarty_security.php b/libs/sysplugins/smarty_security.php index 16a2cd18..6da19c29 100644 --- a/libs/sysplugins/smarty_security.php +++ b/libs/sysplugins/smarty_security.php @@ -141,7 +141,18 @@ class Smarty_Security * @var boolean */ public $allow_super_globals = true; - + /** + * max template nesting level + * + * @var int + */ + public $max_template_nesting = 0; + /** + * current template nesting level + * + * @var int + */ + private $_current_template_nesting = 0; /** * Cache for $resource_dir lookup * @@ -502,4 +513,28 @@ class Smarty_Security throw new SmartyException("directory '{$_filepath}' not allowed by security setting"); } + + /** + * Start template processing + * + * @param $template + * + * @throws SmartyException + */ + public function startTemplate($template) { + if ($this->max_template_nesting > 0 && $this->_current_template_nesting++ >= $this->max_template_nesting) { + throw new SmartyException("maximum template nesting level of '{$this->max_template_nesting}' exceeded when calling '{$template->template_resource}'"); + } + } + + /** + * Exit template processing + * + * @param $template + */ + public function exitTemplate($template) { + if ($this->max_template_nesting > 0) { + $this->_current_template_nesting --; + } + } }