mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-11 18:06:46 +00:00
Fix sandbox support when using include(template_from_string())
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# 1.44.0 (2020-XX-XX)
|
||||
|
||||
* Fix sandbox support when using "include(template_from_string())"
|
||||
* Make round brackets optional for one argument tests like "same as" or "divisible by"
|
||||
* Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a }
|
||||
|
||||
|
||||
@@ -313,6 +313,8 @@ use Twig\Loader\SourceContextLoaderInterface;
|
||||
use Twig\Markup;
|
||||
use Twig\Node\Expression\ConstantExpression;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Template;
|
||||
use Twig\TemplateWrapper;
|
||||
|
||||
/**
|
||||
* Cycles over a value.
|
||||
@@ -1562,6 +1564,11 @@ function twig_include(Environment $env, $context, $template, $variables = [], $w
|
||||
}
|
||||
}
|
||||
|
||||
// if a Template instance is passed, it might have been instantiated outside of a sandbox, check security
|
||||
if ($template instanceof TemplateWrapper || $template instanceof Template) {
|
||||
$template->unwrap()->checkSecurity();
|
||||
}
|
||||
|
||||
$loaded = null;
|
||||
try {
|
||||
$loaded = $env->resolveTemplate($template);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Node;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class CheckSecurityCallNode extends Node
|
||||
{
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("\$this->sandbox = \$this->env->getExtension('\Twig\Extension\SandboxExtension');\n")
|
||||
->write("\$this->checkSecurity();\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -45,10 +45,13 @@ class CheckSecurityNode extends Node
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("\$this->sandbox = \$this->env->getExtension('\Twig\Extension\SandboxExtension');\n")
|
||||
->write('$tags = ')->repr(array_filter($tags))->raw(";\n")
|
||||
->write('$filters = ')->repr(array_filter($filters))->raw(";\n")
|
||||
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
|
||||
->write("\n")
|
||||
->write("public function checkSecurity()\n")
|
||||
->write("{\n")
|
||||
->indent()
|
||||
->write('static $tags = ')->repr(array_filter($tags))->raw(";\n")
|
||||
->write('static $filters = ')->repr(array_filter($filters))->raw(";\n")
|
||||
->write('static $functions = ')->repr(array_filter($functions))->raw(";\n\n")
|
||||
->write("try {\n")
|
||||
->indent()
|
||||
->write("\$this->sandbox->checkSecurity(\n")
|
||||
@@ -78,6 +81,8 @@ class CheckSecurityNode extends Node
|
||||
->write("throw \$e;\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace Twig\NodeVisitor;
|
||||
|
||||
use Twig\Environment;
|
||||
use Twig\Node\CheckSecurityCallNode;
|
||||
use Twig\Node\CheckSecurityNode;
|
||||
use Twig\Node\CheckToStringNode;
|
||||
use Twig\Node\Expression\Binary\ConcatBinary;
|
||||
@@ -102,7 +103,8 @@ class SandboxNodeVisitor extends AbstractNodeVisitor
|
||||
if ($node instanceof ModuleNode) {
|
||||
$this->inAModule = false;
|
||||
|
||||
$node->getNode('constructor_end')->setNode('_security_check', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('display_start')]));
|
||||
$node->setNode('constructor_end', new Node([new CheckSecurityCallNode(), $node->getNode('constructor_end')]));
|
||||
$node->setNode('class_end', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('class_end')]));
|
||||
} elseif ($this->inAModule) {
|
||||
if ($node instanceof PrintNode || $node instanceof SetNode) {
|
||||
$this->needsToStringWrap = false;
|
||||
|
||||
+1
-1
@@ -397,7 +397,7 @@ abstract class Template implements \Twig_TemplateInterface
|
||||
*
|
||||
* @return Template
|
||||
*/
|
||||
protected function unwrap()
|
||||
public function unwrap()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ class SandboxTest extends \PHPUnit\Framework\TestCase
|
||||
$twig->load('1_basic2_include_template_from_string')->render(self::$params);
|
||||
$this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called');
|
||||
} catch (SecurityError $e) {
|
||||
$this->assertInstanceOf(SecurityNotAllowedFilterError::class, $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedFilterError');
|
||||
$this->assertInstanceOf('\Twig\Sandbox\SecurityNotAllowedFilterError', $e, 'Exception should be an instance of Twig_Sandbox_SecurityNotAllowedFilterError');
|
||||
$this->assertEquals('upper', $e->getFilterName(), 'Exception should be raised on the "upper" filter');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user