Forbid access to the Twig environment from template instance

This also forbids access to other internal parts of the Twig_Template.
This commit is contained in:
Christophe Coevoet
2015-08-12 12:44:13 +02:00
committed by Fabien Potencier
parent 30be07759a
commit a8a125ba9b
2 changed files with 24 additions and 2 deletions
+19 -2
View File
@@ -480,7 +480,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
}
// object property
if (self::METHOD_CALL !== $type) {
if (self::METHOD_CALL !== $type && !$object instanceof self) { // Twig_Template does not have public properties, and we don't want to allow access to internal ones
if (isset($object->$item) || array_key_exists((string) $item, $object)) {
if ($isDefinedTest) {
return true;
@@ -498,7 +498,24 @@ abstract class Twig_Template implements Twig_TemplateInterface
// object method
if (!isset(self::$cache[$class]['methods'])) {
self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object)));
// get_class_methods returns all methods accessible in the scope, but we only want public ones to be accessible in templates
if ($object instanceof self) {
$ref = new ReflectionClass($class);
$methods = array();
foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) {
$methodName = strtolower($refMethod->name);
// Accessing the environment from templates is forbidden to prevent untrusted changes to the environment
if ('getenvironment' !== $methodName) {
$methods[$methodName] = true;
}
}
self::$cache[$class]['methods'] = $methods;
} else {
self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object)));
}
}
$call = false;
+5
View File
@@ -147,6 +147,11 @@ class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
$this->assertNotInstanceof('Twig_Markup', $template->getAttribute($template1, 'empty'));
$this->assertSame('', $template->getAttribute($template1, 'empty'));
$this->assertFalse($template->getAttribute($template1, 'env', array(), Twig_Template::ANY_CALL, true));
$this->assertFalse($template->getAttribute($template1, 'environment', array(), Twig_Template::ANY_CALL, true));
$this->assertFalse($template->getAttribute($template1, 'getEnvironment', array(), Twig_Template::METHOD_CALL, true));
$this->assertFalse($template->getAttribute($template1, 'displayWithErrorHandling', array(), Twig_Template::METHOD_CALL, true));
}
public function getGetAttributeWithTemplateAsObject()