mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-13 02:46:29 +00:00
security #cve-2026-46639 Fix sandbox bypass in object destructuring assignment (alexandre-daubois)
This PR was merged into the twig-3.x branch.
This commit is contained in:
@@ -13,6 +13,7 @@ namespace Twig\Node\Expression\Binary;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Error\SyntaxError;
|
||||
use Twig\Extension\SandboxExtension;
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Expression\ArrayExpression;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
@@ -64,7 +65,7 @@ class ObjectDestructuringSetBinary extends AbstractBinary
|
||||
if ($i) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$compiler->raw('CoreExtension::getAttribute($this->env, $this->source, ')->subcompile($this->getNode('right'))->raw(', ')->repr($mapping['property'])->raw(', [], \\Twig\\Template::ANY_CALL, false, false, false, ')->repr($this->getNode('right')->getTemplateLine())->raw(')');
|
||||
$compiler->raw('CoreExtension::getAttribute($this->env, $this->source, ')->subcompile($this->getNode('right'))->raw(', ')->repr($mapping['property'])->raw(', [], \\Twig\\Template::ANY_CALL, false, false, ')->repr($compiler->getEnvironment()->hasExtension(SandboxExtension::class))->raw(', ')->repr($this->getNode('right')->getTemplateLine())->raw(')');
|
||||
}
|
||||
$compiler->raw(']');
|
||||
}
|
||||
|
||||
@@ -423,6 +423,40 @@ class SandboxTest extends TestCase
|
||||
$this->assertEquals('bar', $twig->load('1_basic4')->render(self::$params), 'Sandbox allow some properties');
|
||||
}
|
||||
|
||||
public function testSandboxAllowDestructuring()
|
||||
{
|
||||
$template = '{% do {bar: x, foo: y} = obj %}{{ x }}-{{ y }}';
|
||||
$twig = $this->getEnvironment(true, [], ['index' => $template], ['do'], [], ['Twig\Tests\Extension\FooObject' => 'foo'], ['Twig\Tests\Extension\FooObject' => 'bar']);
|
||||
FooObject::reset();
|
||||
$this->assertSame('bar-foo', $twig->load('index')->render(self::$params), 'Sandbox allows destructuring when properties and methods are allowed');
|
||||
}
|
||||
|
||||
public function testSandboxUnallowedDestructuringProperty()
|
||||
{
|
||||
$template = '{% do {bar: x} = obj %}{{ x }}';
|
||||
$twig = $this->getEnvironment(true, [], ['index' => $template], ['do']);
|
||||
try {
|
||||
$twig->load('index')->render(self::$params);
|
||||
$this->fail('Sandbox throws a SecurityError exception if an unallowed property is read via destructuring');
|
||||
} catch (SecurityNotAllowedPropertyError $e) {
|
||||
$this->assertSame('Twig\Tests\Extension\FooObject', $e->getClassName());
|
||||
$this->assertSame('bar', $e->getPropertyName());
|
||||
}
|
||||
}
|
||||
|
||||
public function testSandboxUnallowedDestructuringMethod()
|
||||
{
|
||||
$template = '{% do {foo: y} = obj %}{{ y }}';
|
||||
$twig = $this->getEnvironment(true, [], ['index' => $template], ['do'], [], [], ['Twig\Tests\Extension\FooObject' => 'foo']);
|
||||
try {
|
||||
$twig->load('index')->render(self::$params);
|
||||
$this->fail('Sandbox throws a SecurityError exception if an unallowed method is called via destructuring');
|
||||
} catch (SecurityNotAllowedMethodError $e) {
|
||||
$this->assertSame('Twig\Tests\Extension\FooObject', $e->getClassName());
|
||||
$this->assertSame('foo', $e->getMethodName());
|
||||
}
|
||||
}
|
||||
|
||||
public function testSandboxAllowFunction()
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], self::$templates, [], [], [], [], ['cycle']);
|
||||
|
||||
Reference in New Issue
Block a user