mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-03 09:54:27 +02:00
commit security features
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/Smarty.addons.php';
|
||||
require_once 'Smarty.addons.php';
|
||||
|
||||
define("SMARTY_PHP_PASSTHRU",0);
|
||||
define("SMARTY_PHP_QUOTE",1);
|
||||
@@ -98,6 +98,16 @@ class Smarty
|
||||
// SMARTY_PHP_REMOVE -> remove php tags
|
||||
// SMARTY_PHP_ALLOW -> execute php tags
|
||||
// default: SMARTY_PHP_PASSTHRU
|
||||
|
||||
|
||||
var $security = false; // enable template security (default false)
|
||||
var $security_settings = array(
|
||||
"ALLOW_PHP_HANDLING" => false,
|
||||
"ALLOW_IF_FUNCS" => array('count','is_array'),
|
||||
"ALLOW_INCLUDE_ANY" => false,
|
||||
"ALLOW_PHP_TAGS" => false,
|
||||
"ALLOW_MODIFIER_FUNCS" => array('count')
|
||||
);
|
||||
|
||||
var $left_delimiter = '{'; // template tag delimiters.
|
||||
var $right_delimiter = '}';
|
||||
@@ -496,7 +506,7 @@ class Smarty
|
||||
if ($this->_conf_obj === null) {
|
||||
/* Prepare the configuration object. */
|
||||
if (!class_exists('Config_File'))
|
||||
include_once dirname(__FILE__) . '/Config_File.class.php';
|
||||
include_once 'Config_File.class.php';
|
||||
$this->_conf_obj = new Config_File($this->config_dir);
|
||||
} else
|
||||
$this->_conf_obj->set_path($this->config_dir);
|
||||
@@ -639,7 +649,14 @@ class Smarty
|
||||
// relative pathname to $template_dir
|
||||
$resource_name = $this->template_dir.'/'.$resource_name;
|
||||
}
|
||||
if (file_exists($resource_name)) {
|
||||
// if security is on, make sure template comes from $template_dir
|
||||
if($this->security && !$this->security_settings["ALLOW_INCLUDE_ANY"]) {
|
||||
if(substr(realpath($resource_name),0,strlen(realpath($this->template_dir))) != realpath($this->template_dir)) {
|
||||
$this->_trigger_error_msg("(secure mode) including \"$resource_name\" is not allowed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (file_exists($resource_name) && is_readable($resource_name)) {
|
||||
$template_source = $this->_read_file($resource_name);
|
||||
$template_timestamp = filemtime($resource_name);
|
||||
return true;
|
||||
@@ -676,7 +693,7 @@ class Smarty
|
||||
\*======================================================================*/
|
||||
function _compile_template($tpl_file, $template_source, &$template_compiled)
|
||||
{
|
||||
include_once dirname(__FILE__) . '/' . $this->compiler_class . '.class.php';
|
||||
include_once $this->compiler_class . '.class.php';
|
||||
|
||||
$smarty_compiler = new $this->compiler_class;
|
||||
|
||||
@@ -693,6 +710,8 @@ class Smarty
|
||||
$smarty_compiler->_version = $this->_version;
|
||||
$smarty_compiler->prefilter_funcs = $this->prefilter_funcs;
|
||||
$smarty_compiler->compiler_funcs = $this->compiler_funcs;
|
||||
$smarty_compiler->security = $this->security;
|
||||
$smarty_compiler->security_settings = $this->security_settings;
|
||||
|
||||
if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled))
|
||||
return true;
|
||||
|
@@ -54,7 +54,15 @@ class Smarty_Compiler extends Smarty {
|
||||
\*======================================================================*/
|
||||
function _compile_file($tpl_file, $template_source, &$template_compiled)
|
||||
{
|
||||
|
||||
|
||||
if($this->security) {
|
||||
// do not allow php syntax to be executed unless specified
|
||||
if($this->php_handling == SMARTY_PHP_ALLOW &&
|
||||
!$this->security_settings["ALLOW_PHP_HANDLING"]) {
|
||||
$this->php_handling = SMARTY_PHP_PASSTHRU;
|
||||
}
|
||||
}
|
||||
|
||||
// run template source through functions registered in prefilter_funcs
|
||||
if (is_array($this->prefilter_funcs) && count($this->prefilter_funcs) > 0) {
|
||||
foreach($this->prefilter_funcs as $prefilter) {
|
||||
@@ -240,6 +248,10 @@ class Smarty_Compiler extends Smarty {
|
||||
return "<?php echo '".str_replace("'","\'",$literal_block)."'; ?>\n";
|
||||
|
||||
case 'php':
|
||||
if($this->security && !$this->security_settings["ALLOW_PHP_TAGS"]) {
|
||||
$this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
list (,$php_block) = each($this->_php_blocks);
|
||||
$this->_current_line_no += substr_count($php_block, "\n");
|
||||
return '<?php '.$php_block.' ?>';
|
||||
@@ -833,8 +845,14 @@ class Smarty_Compiler extends Smarty {
|
||||
* If we don't find that modifier there, we assume it's just a PHP
|
||||
* function name.
|
||||
*/
|
||||
if (!isset($mod_func_name))
|
||||
$mod_func_name = $modifier_name;
|
||||
if (!isset($mod_func_name)) {
|
||||
if($this->security && !in_array($modifier_name,$this->security_settings["ALLOW_MODIFIER_FUNCS"])) {
|
||||
$this->_syntax_error("(secure mode) modifier '$modifier_name' is not allowed", E_USER_WARNING);
|
||||
continue;
|
||||
} else {
|
||||
$mod_func_name = $modifier_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists($mod_func_name)) {
|
||||
$this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING);
|
||||
|
@@ -6,7 +6,7 @@ $smarty = new Smarty;
|
||||
|
||||
$smarty->compile_check = true;
|
||||
|
||||
$smarty->assign(now, time());
|
||||
$smarty->assign("now", time());
|
||||
|
||||
$smarty->assign("Name","Fred Irving Johnathan Bradley Peppergill");
|
||||
$smarty->assign("FirstName",array("John","Mary","James","Henry"));
|
||||
|
@@ -3267,7 +3267,7 @@ OUTPUT:
|
||||
<entry>numeric</entry>
|
||||
<entry>Yes</entry>
|
||||
<entry><emphasis>n/a</emphasis></entry>
|
||||
<entry>equation varible value</entry>
|
||||
<entry>equation variable value</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
@@ -4230,7 +4230,7 @@ footer.tpl
|
||||
When the main page is drawn, the title of "Main Page" is passed to the
|
||||
header.tpl, and will subsequently be used as the title. When the
|
||||
archives page is drawn, the title will be "Archives". Notice in the
|
||||
archive example, we are using a varible from the archives_page.conf
|
||||
archive example, we are using a variable from the archives_page.conf
|
||||
file instead of a hard coded variable. Also notice that "BC News" is
|
||||
printed if the $title variable is not set, using the
|
||||
<emphasis>default</emphasis> variable modifier.
|
||||
|
@@ -6,7 +6,7 @@ $smarty = new Smarty;
|
||||
|
||||
$smarty->compile_check = true;
|
||||
|
||||
$smarty->assign(now, time());
|
||||
$smarty->assign("now", time());
|
||||
|
||||
$smarty->assign("Name","Fred Irving Johnathan Bradley Peppergill");
|
||||
$smarty->assign("FirstName",array("John","Mary","James","Henry"));
|
||||
|
@@ -40,7 +40,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/Smarty.addons.php';
|
||||
require_once 'Smarty.addons.php';
|
||||
|
||||
define("SMARTY_PHP_PASSTHRU",0);
|
||||
define("SMARTY_PHP_QUOTE",1);
|
||||
@@ -98,6 +98,16 @@ class Smarty
|
||||
// SMARTY_PHP_REMOVE -> remove php tags
|
||||
// SMARTY_PHP_ALLOW -> execute php tags
|
||||
// default: SMARTY_PHP_PASSTHRU
|
||||
|
||||
|
||||
var $security = false; // enable template security (default false)
|
||||
var $security_settings = array(
|
||||
"ALLOW_PHP_HANDLING" => false,
|
||||
"ALLOW_IF_FUNCS" => array('count','is_array'),
|
||||
"ALLOW_INCLUDE_ANY" => false,
|
||||
"ALLOW_PHP_TAGS" => false,
|
||||
"ALLOW_MODIFIER_FUNCS" => array('count')
|
||||
);
|
||||
|
||||
var $left_delimiter = '{'; // template tag delimiters.
|
||||
var $right_delimiter = '}';
|
||||
@@ -496,7 +506,7 @@ class Smarty
|
||||
if ($this->_conf_obj === null) {
|
||||
/* Prepare the configuration object. */
|
||||
if (!class_exists('Config_File'))
|
||||
include_once dirname(__FILE__) . '/Config_File.class.php';
|
||||
include_once 'Config_File.class.php';
|
||||
$this->_conf_obj = new Config_File($this->config_dir);
|
||||
} else
|
||||
$this->_conf_obj->set_path($this->config_dir);
|
||||
@@ -639,7 +649,14 @@ class Smarty
|
||||
// relative pathname to $template_dir
|
||||
$resource_name = $this->template_dir.'/'.$resource_name;
|
||||
}
|
||||
if (file_exists($resource_name)) {
|
||||
// if security is on, make sure template comes from $template_dir
|
||||
if($this->security && !$this->security_settings["ALLOW_INCLUDE_ANY"]) {
|
||||
if(substr(realpath($resource_name),0,strlen(realpath($this->template_dir))) != realpath($this->template_dir)) {
|
||||
$this->_trigger_error_msg("(secure mode) including \"$resource_name\" is not allowed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (file_exists($resource_name) && is_readable($resource_name)) {
|
||||
$template_source = $this->_read_file($resource_name);
|
||||
$template_timestamp = filemtime($resource_name);
|
||||
return true;
|
||||
@@ -676,7 +693,7 @@ class Smarty
|
||||
\*======================================================================*/
|
||||
function _compile_template($tpl_file, $template_source, &$template_compiled)
|
||||
{
|
||||
include_once dirname(__FILE__) . '/' . $this->compiler_class . '.class.php';
|
||||
include_once $this->compiler_class . '.class.php';
|
||||
|
||||
$smarty_compiler = new $this->compiler_class;
|
||||
|
||||
@@ -693,6 +710,8 @@ class Smarty
|
||||
$smarty_compiler->_version = $this->_version;
|
||||
$smarty_compiler->prefilter_funcs = $this->prefilter_funcs;
|
||||
$smarty_compiler->compiler_funcs = $this->compiler_funcs;
|
||||
$smarty_compiler->security = $this->security;
|
||||
$smarty_compiler->security_settings = $this->security_settings;
|
||||
|
||||
if ($smarty_compiler->_compile_file($tpl_file, $template_source, $template_compiled))
|
||||
return true;
|
||||
|
@@ -54,7 +54,15 @@ class Smarty_Compiler extends Smarty {
|
||||
\*======================================================================*/
|
||||
function _compile_file($tpl_file, $template_source, &$template_compiled)
|
||||
{
|
||||
|
||||
|
||||
if($this->security) {
|
||||
// do not allow php syntax to be executed unless specified
|
||||
if($this->php_handling == SMARTY_PHP_ALLOW &&
|
||||
!$this->security_settings["ALLOW_PHP_HANDLING"]) {
|
||||
$this->php_handling = SMARTY_PHP_PASSTHRU;
|
||||
}
|
||||
}
|
||||
|
||||
// run template source through functions registered in prefilter_funcs
|
||||
if (is_array($this->prefilter_funcs) && count($this->prefilter_funcs) > 0) {
|
||||
foreach($this->prefilter_funcs as $prefilter) {
|
||||
@@ -240,6 +248,10 @@ class Smarty_Compiler extends Smarty {
|
||||
return "<?php echo '".str_replace("'","\'",$literal_block)."'; ?>\n";
|
||||
|
||||
case 'php':
|
||||
if($this->security && !$this->security_settings["ALLOW_PHP_TAGS"]) {
|
||||
$this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
list (,$php_block) = each($this->_php_blocks);
|
||||
$this->_current_line_no += substr_count($php_block, "\n");
|
||||
return '<?php '.$php_block.' ?>';
|
||||
@@ -833,8 +845,14 @@ class Smarty_Compiler extends Smarty {
|
||||
* If we don't find that modifier there, we assume it's just a PHP
|
||||
* function name.
|
||||
*/
|
||||
if (!isset($mod_func_name))
|
||||
$mod_func_name = $modifier_name;
|
||||
if (!isset($mod_func_name)) {
|
||||
if($this->security && !in_array($modifier_name,$this->security_settings["ALLOW_MODIFIER_FUNCS"])) {
|
||||
$this->_syntax_error("(secure mode) modifier '$modifier_name' is not allowed", E_USER_WARNING);
|
||||
continue;
|
||||
} else {
|
||||
$mod_func_name = $modifier_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists($mod_func_name)) {
|
||||
$this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING);
|
||||
|
Reference in New Issue
Block a user