mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-16 12:26:30 +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)
|
# 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"
|
* 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 }
|
* 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\Markup;
|
||||||
use Twig\Node\Expression\ConstantExpression;
|
use Twig\Node\Expression\ConstantExpression;
|
||||||
use Twig\Node\Node;
|
use Twig\Node\Node;
|
||||||
|
use Twig\Template;
|
||||||
|
use Twig\TemplateWrapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cycles over a value.
|
* 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;
|
$loaded = null;
|
||||||
try {
|
try {
|
||||||
$loaded = $env->resolveTemplate($template);
|
$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
|
$compiler
|
||||||
->write("\$this->sandbox = \$this->env->getExtension('\Twig\Extension\SandboxExtension');\n")
|
->write("\n")
|
||||||
->write('$tags = ')->repr(array_filter($tags))->raw(";\n")
|
->write("public function checkSecurity()\n")
|
||||||
->write('$filters = ')->repr(array_filter($filters))->raw(";\n")
|
->write("{\n")
|
||||||
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\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")
|
->write("try {\n")
|
||||||
->indent()
|
->indent()
|
||||||
->write("\$this->sandbox->checkSecurity(\n")
|
->write("\$this->sandbox->checkSecurity(\n")
|
||||||
@@ -78,6 +81,8 @@ class CheckSecurityNode extends Node
|
|||||||
->write("throw \$e;\n")
|
->write("throw \$e;\n")
|
||||||
->outdent()
|
->outdent()
|
||||||
->write("}\n\n")
|
->write("}\n\n")
|
||||||
|
->outdent()
|
||||||
|
->write("}\n")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
namespace Twig\NodeVisitor;
|
namespace Twig\NodeVisitor;
|
||||||
|
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
|
use Twig\Node\CheckSecurityCallNode;
|
||||||
use Twig\Node\CheckSecurityNode;
|
use Twig\Node\CheckSecurityNode;
|
||||||
use Twig\Node\CheckToStringNode;
|
use Twig\Node\CheckToStringNode;
|
||||||
use Twig\Node\Expression\Binary\ConcatBinary;
|
use Twig\Node\Expression\Binary\ConcatBinary;
|
||||||
@@ -102,7 +103,8 @@ class SandboxNodeVisitor extends AbstractNodeVisitor
|
|||||||
if ($node instanceof ModuleNode) {
|
if ($node instanceof ModuleNode) {
|
||||||
$this->inAModule = false;
|
$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) {
|
} elseif ($this->inAModule) {
|
||||||
if ($node instanceof PrintNode || $node instanceof SetNode) {
|
if ($node instanceof PrintNode || $node instanceof SetNode) {
|
||||||
$this->needsToStringWrap = false;
|
$this->needsToStringWrap = false;
|
||||||
|
|||||||
+1
-1
@@ -397,7 +397,7 @@ abstract class Template implements \Twig_TemplateInterface
|
|||||||
*
|
*
|
||||||
* @return Template
|
* @return Template
|
||||||
*/
|
*/
|
||||||
protected function unwrap()
|
public function unwrap()
|
||||||
{
|
{
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class SandboxTest extends \PHPUnit\Framework\TestCase
|
|||||||
$twig->load('1_basic2_include_template_from_string')->render(self::$params);
|
$twig->load('1_basic2_include_template_from_string')->render(self::$params);
|
||||||
$this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called');
|
$this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called');
|
||||||
} catch (SecurityError $e) {
|
} 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');
|
$this->assertEquals('upper', $e->getFilterName(), 'Exception should be raised on the "upper" filter');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user