Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3fe13f9

Browse files
Fix sandbox bypass in object destructuring assignment
1 parent 9c85915 commit 3fe13f9

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

src/Node/Expression/Binary/ObjectDestructuringSetBinary.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Twig\Compiler;
1515
use Twig\Error\SyntaxError;
16+
use Twig\Extension\SandboxExtension;
1617
use Twig\Node\Expression\AbstractExpression;
1718
use Twig\Node\Expression\ArrayExpression;
1819
use Twig\Node\Expression\Variable\ContextVariable;
@@ -64,7 +65,7 @@ public function compile(Compiler $compiler): void
6465
if ($i) {
6566
$compiler->raw(', ');
6667
}
67-
$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(')');
68+
$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(')');
6869
}
6970
$compiler->raw(']');
7071
}

tests/Extension/SandboxTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,40 @@ public function testSandboxAllowProperty()
423423
$this->assertEquals('bar', $twig->load('1_basic4')->render(self::$params), 'Sandbox allow some properties');
424424
}
425425

426+
public function testSandboxAllowDestructuring()
427+
{
428+
$template = '{% do {bar: x, foo: y} = obj %}{{ x }}-{{ y }}';
429+
$twig = $this->getEnvironment(true, [], ['index' => $template], ['do'], [], ['Twig\Tests\Extension\FooObject' => 'foo'], ['Twig\Tests\Extension\FooObject' => 'bar']);
430+
FooObject::reset();
431+
$this->assertSame('bar-foo', $twig->load('index')->render(self::$params), 'Sandbox allows destructuring when properties and methods are allowed');
432+
}
433+
434+
public function testSandboxUnallowedDestructuringProperty()
435+
{
436+
$template = '{% do {bar: x} = obj %}{{ x }}';
437+
$twig = $this->getEnvironment(true, [], ['index' => $template], ['do']);
438+
try {
439+
$twig->load('index')->render(self::$params);
440+
$this->fail('Sandbox throws a SecurityError exception if an unallowed property is read via destructuring');
441+
} catch (SecurityNotAllowedPropertyError $e) {
442+
$this->assertSame('Twig\Tests\Extension\FooObject', $e->getClassName());
443+
$this->assertSame('bar', $e->getPropertyName());
444+
}
445+
}
446+
447+
public function testSandboxUnallowedDestructuringMethod()
448+
{
449+
$template = '{% do {foo: y} = obj %}{{ y }}';
450+
$twig = $this->getEnvironment(true, [], ['index' => $template], ['do'], [], [], ['Twig\Tests\Extension\FooObject' => 'foo']);
451+
try {
452+
$twig->load('index')->render(self::$params);
453+
$this->fail('Sandbox throws a SecurityError exception if an unallowed method is called via destructuring');
454+
} catch (SecurityNotAllowedMethodError $e) {
455+
$this->assertSame('Twig\Tests\Extension\FooObject', $e->getClassName());
456+
$this->assertSame('foo', $e->getMethodName());
457+
}
458+
}
459+
426460
public function testSandboxAllowFunction()
427461
{
428462
$twig = $this->getEnvironment(true, [], self::$templates, [], [], [], [], ['cycle']);

0 commit comments

Comments
 (0)