Skip to content

安全性 {/programmers/advanced-features/.security}

当你面临不信任的第三方编辑模板(例如,通过 FTP)的情况时,安全性就显得非常重要,你会希望通过模板语言来降低系统安全性受损的风险。

安全策略的设置由 Smarty_Security 类的一个实例的属性来定义。以下是可能的设置:

  • $secure_dir 是被视为安全的模板目录的数组。$template_dir 被隐式地视为安全的。默认是一个空数组。

  • $trusted_dir 是被视为可信的所有目录的数组。可信目录是你存放可以直接从模板中执行的 php 脚本的地方,使用 {insert}。默认是一个空数组。

  • $trusted_uri 是被视为可信的匹配 URI 的正则表达式数组。这个安全指令被 {fetch}{html_image} 使用。传递给这些函数的 URI 被简化为 {$PROTOCOL}://{$HOSTNAME} ,以便使用简单的正则表达式(不必处理像认证令牌这样的边缘情况)。

表达式 '#https?://.*smarty.net$#i' 会允许访问以下 URI:

  • http://smarty.net/foo

  • http://smarty.net/foo

  • http://www.smarty.net/foo

  • http://smarty.net/foo

  • https://foo.bar.www.smarty.net/foo/bla?blubb=1

但拒绝访问这些 URI:

  • http://smarty.com/foo (不匹配顶级域名 \"com\")

  • ftp://www.smarty.net/foo (不匹配协议 \"ftp\")

  • http://www.smarty.net.otherdomain.com/foo (不匹配域名结束部分 \"smarty.net\")

  • $static_classes 是被视为可信的类的数组。默认是一个空数组,允许访问所有静态类。要禁止访问所有静态类,请设置 \$static_classes = null。

  • $php_functions 是被视为可信的 PHP 函数的数组,可以在模板内部使用。要禁止访问所有 PHP 函数,请设置 \$php_functions = null。一个空数组 ( \$php_functions = array() ) 将允许所有 PHP 函数。默认是数组 ('isset', 'empty', 'count', 'sizeof', 'in_array', 'is_array','time','nl2br')。

  • $php_modifiers 是被视为可信的 PHP 函数的数组,可以在模板内部作为修饰符使用。要禁止访问所有 PHP 修饰符,请设置 \$php_modifier = null。一个空数组 ( \$php_modifier = array() ) 将允许所有 PHP 函数。默认是数组 ('escape','count')。

  • $streams 是被视为可信的流的数组,可以在模板内部使用。要禁止访问所有流,请设置 \$streams = null。一个空数组 ( \$streams = array() ) 将允许所有流。默认是数组 ('file')。

  • $allowed_modifiers 是一个数组,包含应该对模板可访问的(已注册/自动加载的)修饰符。如果这个数组非空,只有列在其中的修饰符才可以使用。这是一个白名单。

  • $disabled_modifiers 是一个数组,包含可能不被模板访问的(已注册/自动加载的)修饰符。

  • $allowed_tags 是一个布尔标记,控制常量是否可以作为函数、块和过滤器插件对模板可访问。如果这个数组非空,只有列在其中的修饰符才可以使用。这是一个白名单。

  • $disabled_tags 是一个数组,包含可能不被模板访问的(已注册/自动加载的)函数、块和过滤器插件。

  • $allow_constants 是一个布尔标记,控制模板是否可以访问常量。默认是 \"true\"。

  • $allow_super_globals 是一个布尔标记,控制模板是否可以访问 PHP 的超全局变量。默认是 \"true\"。

如果启用了安全性,模板无法访问静态类或分配对象的任何私有方法、函数或属性(以'__'开头)。

要自定义安全策略设置,你可以扩展 Smarty_Security 类或创建它的一个实例。

<?php
require 'Smarty.class.php';

class My_Security_Policy extends Smarty_Security {
  // 禁用所有PHP函数
  public $php_functions = null;
  // 允许所有内容作为修饰符
  public $php_modifiers = array();
}
$smarty = new Smarty();
// 启用安全性
$smarty->enableSecurity('My_Security_Policy');
?>


<?php
require 'Smarty.class.php';
$smarty = new Smarty();
$my_security_policy = new Smarty_Security($smarty);
// 禁用所有PHP函数
$my_security_policy->php_functions = null;
// 允许所有内容作为修饰符
$my_security_policy->php_modifiers = array();
// 启用安全性
$smarty->enableSecurity($my_security_policy);
?>


<?php
require 'Smarty.class.php';
$smarty = new Smarty();
// 启用默认安全性
$smarty->enableSecurity();
?>

注意

大多数安全策略设置只在模板被编译时检查。因此,当你更改安全设置时,你应删除所有的缓存和编译的模板文件。