Twig 沙箱
sandbox
扩展可以用于评估不受信任的代码。
注册沙箱
通过 addExtension()
方法注册 SandboxExtension
扩展
1
$twig->addExtension(new \Twig\Extension\SandboxExtension($policy));
配置沙箱策略
沙箱安全性由策略实例管理,该实例必须传递给 SandboxExtension
构造函数。
默认情况下,Twig 附带一个策略类:\Twig\Sandbox\SecurityPolicy
。此类允许您允许列出某些标签、过滤器、函数,以及对象上的属性和方法
1 2 3 4 5 6 7 8 9 10
$tags = ['if'];
$filters = ['upper'];
$methods = [
'Article' => ['getTitle', 'getBody'],
];
$properties = [
'Article' => ['title', 'body'],
];
$functions = ['range'];
$policy = new \Twig\Sandbox\SecurityPolicy($tags, $filters, $methods, $properties, $functions);
使用之前的配置,安全策略将仅允许使用 if
标签和 upper
过滤器。此外,模板将只能在 Article
对象上调用 getTitle()
和 getBody()
方法,以及 title
和 body
公共属性。其他一切都将不被允许,并将生成 \Twig\Sandbox\SecurityError
异常。
注意
从 Twig 3.14.1(以及 Twig 3.11.2)开始,如果 Article
类实现了 ArrayAccess
接口,则模板将只能访问 title
和 body
属性。
请注意,原生类数组类(如 ArrayObject
)始终被允许,您无需配置它们。
注意
extends
和 use
标签始终在沙箱模板中被允许。该行为将在 4.0 中更改,届时这些标签将需要像任何其他标签一样被显式允许。
启用沙箱
默认情况下,沙箱模式被禁用,应在使用 include
函数的 sandboxed
选项包含不受信任的模板代码时启用
1
{{ include('user.html.twig', sandboxed: true) }}
您可以通过将 true
作为扩展构造函数的第二个参数传递来沙箱化所有模板
1
$sandbox = new \Twig\Extension\SandboxExtension($policy, true);
接受可调用参数
Twig 沙箱允许您配置允许哪些函数、过滤器、测试和点运算。这些调用中的许多调用可以接受参数。由于这些参数未经过沙箱验证,因此您必须非常小心。
例如,接受 PHP callable
作为参数是危险的,因为它允许最终用户调用任何 PHP 函数(通过传递 string
)或任何静态方法(通过传递 array
)。例如,它将接受任何 PHP 内置函数,如 system()
或 exec()
1 2 3 4 5
$twig->addFilter(new \Twig\TwigFilter('custom', function (callable $callable) {
// ...
$callable();
// ...
}));
为了避免此安全问题,请勿使用 callable
类型提示此类参数,而应使用 \Closure
代替(不使用类型提示也会有问题)。这会将允许的可调用对象限制为仅 PHP 闭包,这足以接受 Twig 箭头函数
1 2 3 4 5 6 7
$twig->addFilter(new \Twig\TwigFilter('custom', function (\Closure $callable) {
// ...
$callable();
// ...
}));
{{ people|custom(p => p.username|join(', ') }}
任何 PHP 可调用对象都可以通过使用 first-class callable syntax 轻松转换为闭包。