Affected versions

Twig 1.0.0 to 1.37.1 and 2.0.0 to 2.6.2 are affected by this security issue.

The issue has been fixed in Twig 1.38.0 and 2.7.0.

Description

This vulnerability affects the sandbox mode of Twig. If you are not using the sandbox, your code is not affected.

Twig allows the evaluation of non-trusted templates in a sandbox, where everything is forbidden if not explicitly allowed by a sandbox policy (tags, filters, functions, method calls, ...).

For instance, {% if true %}...{% endif %} is not allowed in a sandbox if the if tag has not been explicitly allowed in the sandbox policy.

There is an edge case related to how PHP works. When using {{ var }} with var being an object, PHP will automatically cast the object to a string (echo $var is equivalent to echo $var->__toString()).

If you don't allow __toString() on the class of var, this code will throw a sandbox policy exception.

But unfortunately, the protection against calling __toString() only works for simple cases like the one mentioned above. It does not work on the following template for instance: {{var|upper }} where __toString() will be called even if not part of the policy.

As __toString() is sometimes used in classes to return some debug information, bypassing the policy might disclose sensitive information like database entry ids, usernames, or more.

Resolution

I have rewritten the current strategy that prevents __toString() to be called when not whitelisted with a different approach that tries to spot when PHP will cast objects to strings automatically (echo is one of them, concatenation is another one). The patch for this issue is available here for the 1.x branch.

Credits

I found this issue while working on Twig 3.x, and I provided a patch to fix the issue. I'd like to thank the Symfony core team for the patch review.