Skip to content

Commit

Permalink
Forbid access to the Twig environment from template instance
Browse files Browse the repository at this point in the history
This also forbids access to other internal parts of the Twig_Template.
  • Loading branch information
stof authored and fabpot committed Aug 12, 2015
1 parent 30be077 commit a8a125b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
21 changes: 19 additions & 2 deletions lib/Twig/Template.php
Expand Up @@ -480,7 +480,7 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ
}

// 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;
Expand All @@ -498,7 +498,24 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ

// 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;
Expand Down
5 changes: 5 additions & 0 deletions test/Twig/Tests/TemplateTest.php
Expand Up @@ -147,6 +147,11 @@ public function testGetAttributeWithTemplateAsObject($useExt)

$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()
Expand Down

0 comments on commit a8a125b

Please sign in to comment.