Twig

The flexible, fast, and secure
template engine for PHP

a Symfony Product
Docs Twig Sandbox
You are reading the documentation for Twig 3.x. Switch to the documentation for Twig 1.x, 2.x.

Questions & Feedback

License

Twig documentation is licensed under the new BSD license.

Twig Sandbox

The sandbox extension can be used to evaluate untrusted code.

Registering the Sandbox

Register the SandboxExtension extension via the addExtension() method:

1
$twig->addExtension(new \Twig\Extension\SandboxExtension($policy));

Configuring the Sandbox Policy

The sandbox security is managed by a policy instance, which must be passed to the SandboxExtension constructor.

By default, Twig comes with one policy class: \Twig\Sandbox\SecurityPolicy. This class allows you to allow-list some tags, filters, functions, but also properties and methods on objects:

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);

With the previous configuration, the security policy will only allow usage of the if tag, and the upper filter. Moreover, the templates will only be able to call the getTitle() and getBody() methods on Article objects, and the title and body public properties. Everything else won't be allowed and will generate a \Twig\Sandbox\SecurityError exception.

Note

As of Twig 3.14.1 (and on Twig 3.11.2), if the Article class implements the ArrayAccess interface, the templates will only be able to access the title and body attributes.

Note that native array-like classes (like ArrayObject) are always allowed, you don't need to configure them.

Caution

The extends and use tags are always allowed in a sandboxed template. That behavior will change in 4.0 where these tags will need to be explicitly allowed like any other tag.

Enabling the Sandbox

By default, the sandbox mode is disabled and should be enabled when including untrusted template code by using the sandboxed option of the include function:

1
{{ include('user.html', sandboxed: true) }}

You can sandbox all templates by passing true as the second argument of the extension constructor:

1
$sandbox = new \Twig\Extension\SandboxExtension($policy, true);

Accepting Callables Arguments

The Twig sandbox allows you to configure which functions, filters, tests and dot operations are allowed. Many of these calls can accept arguments. As these arguments are not validated by the sandbox, you must be very careful.

For instance, accepting a PHP callable as an argument is dangerous as it allows end user to call any PHP function (by passing a string) or any static methods (by passing an array). For instance, it would accept any PHP built-in functions like system() or exec():

1
2
3
4
5
$twig->addFilter(new \Twig\TwigFilter('custom', function (callable $callable) {
    // ...
    $callable();
    // ...
}));

To avoid this security issue, don't type-hint such arguments with callable but use \Closure instead (not using a type-hint would also be problematic). This restricts the allowed callables to PHP closures only, which is enough to accept Twig arrow functions:

1
2
3
4
5
6
7
$twig->addFilter(new \Twig\TwigFilter('custom', function (\Closure $callable) {
    // ...
    $callable();
    // ...
}));

{{ people|custom(p => p.username|join(', ') }}

Any PHP callable can easily be converted to a closure by using the first-class callable syntax.