Twig

灵活、快速且安全的
PHP 模板引擎

a Symfony Product
文档 Twig 沙箱
您正在阅读 Twig 3.x 的文档。切换到 Twig 1.x, 2.x 的文档。

问题与反馈

许可证

Twig 文档 在新的 BSD 许可证 下获得许可。

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() 方法,以及 titlebody 公共属性。其他一切都将不被允许,并将生成 \Twig\Sandbox\SecurityError 异常。

注意

从 Twig 3.14.1(以及 Twig 3.11.2)开始,如果 Article 类实现了 ArrayAccess 接口,则模板将只能访问 titlebody 属性。

请注意,原生类数组类(如 ArrayObject)始终被允许,您无需配置它们。

注意

extendsuse 标签始终在沙箱模板中被允许。该行为将在 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 轻松转换为闭包。