From: Fabien Potencier Date: Fri, 26 Nov 2010 21:15:05 +0000 (+0100) Subject: fixed __toString() calls when sandbox is enabled X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=7cdada5d05b8b184b3d71d3e69cbaa3ca7315ab4;p=web%2Fkonrad%2Ftwig.git fixed __toString() calls when sandbox is enabled --- diff --git a/lib/Twig/Node/SandboxedPrint.php b/lib/Twig/Node/SandboxedPrint.php index 773b0f3..34db421 100644 --- a/lib/Twig/Node/SandboxedPrint.php +++ b/lib/Twig/Node/SandboxedPrint.php @@ -36,17 +36,18 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print { $compiler ->addDebugInfo($this) - ->write('if ($this->env->hasExtension(\'sandbox\') && is_object(') + ->write('$_tmp = ') ->subcompile($this->getNode('expr')) - ->raw(')) {'."\n") + ->raw(";\n") + ->write('if (is_object(') + ->raw('$_tmp)) {'."\n") ->indent() ->write('$this->env->getExtension(\'sandbox\')->checkMethodAllowed(') - ->subcompile($this->getNode('expr')) - ->raw(', \'__toString\');'."\n") + ->raw('$_tmp, \'__toString\');'."\n") ->outdent() ->write('}'."\n") + ->write('echo ') + ->raw("\$_tmp;\n") ; - - parent::compile($compiler); } } diff --git a/lib/Twig/NodeVisitor/Sandbox.php b/lib/Twig/NodeVisitor/Sandbox.php index 77a507b..542b730 100644 --- a/lib/Twig/NodeVisitor/Sandbox.php +++ b/lib/Twig/NodeVisitor/Sandbox.php @@ -48,8 +48,8 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface $this->filters[] = $node->getNode('filter')->getAttribute('value'); } - // look for simple print statements ({{ article }}) - if ($node instanceof Twig_Node_Print && $node->getNode('expr') instanceof Twig_Node_Expression_Name) { + // wrap print to check __toString() calls + if ($node instanceof Twig_Node_Print) { return new Twig_Node_SandboxedPrint($node); } } diff --git a/test/Twig/Tests/Extension/SandboxTest.php b/test/Twig/Tests/Extension/SandboxTest.php index a939ffd..33692ab 100644 --- a/test/Twig/Tests/Extension/SandboxTest.php +++ b/test/Twig/Tests/Extension/SandboxTest.php @@ -18,6 +18,7 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase self::$params = array( 'name' => 'Fabien', 'obj' => new Object(), + 'arr' => array('obj' => new Object()), ); self::$templates = array( @@ -26,6 +27,7 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase '1_basic3' => '{% if name %}foo{% endif %}', '1_basic4' => '{{ obj.bar }}', '1_basic5' => '{{ obj }}', + '1_basic6' => '{{ arr.obj }}', '1_basic' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', ); } @@ -70,6 +72,13 @@ class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase } catch (Twig_Sandbox_SecurityError $e) { } + $twig = $this->getEnvironment(true, self::$templates); + try { + $twig->loadTemplate('1_basic6')->render(self::$params); + $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template'); + } catch (Twig_Sandbox_SecurityError $e) { + } + $twig = $this->getEnvironment(true, self::$templates, array(), array(), array('Object' => 'foo')); $this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods'); diff --git a/test/Twig/Tests/Node/SandboxedPrintTest.php b/test/Twig/Tests/Node/SandboxedPrintTest.php index a326005..3e53b6e 100644 --- a/test/Twig/Tests/Node/SandboxedPrintTest.php +++ b/test/Twig/Tests/Node/SandboxedPrintTest.php @@ -40,10 +40,11 @@ class Twig_Tests_Node_SandboxedPrintTest extends Twig_Tests_Node_TestCase $node = new Twig_Node_Print(new Twig_Node_Expression_Constant('foo', 0), 0); $tests[] = array(new Twig_Node_SandboxedPrint($node), <<env->hasExtension('sandbox') && is_object("foo")) { - \$this->env->getExtension('sandbox')->checkMethodAllowed("foo", '__toString'); +\$_tmp = "foo"; +if (is_object(\$_tmp)) { + \$this->env->getExtension('sandbox')->checkMethodAllowed(\$_tmp, '__toString'); } -echo "foo"; +echo \$_tmp; EOF );