Skip to content

Commit 2102dd1

Browse files
committedSep 9, 2024··
Fix a security issue when an included sandboxed template has been loaded before without the sandbox context
1 parent a1d84cf commit 2102dd1

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed
 

‎src/Extension/CoreExtension.php

+4-7
Original file line numberDiff line numberDiff line change
@@ -1268,13 +1268,6 @@ function twig_include(Environment $env, $context, $template, $variables = [], $w
12681268
if (!$alreadySandboxed = $sandbox->isSandboxed()) {
12691269
$sandbox->enableSandbox();
12701270
}
1271-
1272-
foreach ((\is_array($template) ? $template : [$template]) as $name) {
1273-
// if a Template instance is passed, it might have been instantiated outside of a sandbox, check security
1274-
if ($name instanceof TemplateWrapper || $name instanceof Template) {
1275-
$name->unwrap()->checkSecurity();
1276-
}
1277-
}
12781271
}
12791272

12801273
try {
@@ -1287,6 +1280,10 @@ function twig_include(Environment $env, $context, $template, $variables = [], $w
12871280
}
12881281
}
12891282

1283+
if ($isSandboxed && $loaded) {
1284+
$loaded->unwrap()->checkSecurity();
1285+
}
1286+
12901287
return $loaded ? $loaded->render($variables) : '';
12911288
} finally {
12921289
if ($isSandboxed && !$alreadySandboxed) {

‎tests/Extension/CoreTest.php

+38
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Twig\Environment;
1616
use Twig\Error\RuntimeError;
17+
use Twig\Extension\SandboxExtension;
18+
use Twig\Loader\ArrayLoader;
1719
use Twig\Loader\LoaderInterface;
20+
use Twig\Sandbox\SecurityError;
21+
use Twig\Sandbox\SecurityPolicy;
1822

1923
class CoreTest extends TestCase
2024
{
@@ -251,6 +255,40 @@ public function provideSliceFilterCases()
251255
[[], new \ArrayIterator([1, 2]), 3],
252256
];
253257
}
258+
259+
public function testSandboxedInclude()
260+
{
261+
$twig = new Environment(new ArrayLoader([
262+
'index' => '{{ include("included", sandboxed=true) }}',
263+
'included' => '{{ "included"|e }}',
264+
]));
265+
$policy = new SecurityPolicy([], [], [], [], ['include']);
266+
$sandbox = new SandboxExtension($policy, false);
267+
$twig->addExtension($sandbox);
268+
269+
// We expect a compile error
270+
$this->expectException(SecurityError::class);
271+
$twig->render('index');
272+
}
273+
274+
public function testSandboxedIncludeWithPreloadedTemplate()
275+
{
276+
$twig = new Environment(new ArrayLoader([
277+
'index' => '{{ include("included", sandboxed=true) }}',
278+
'included' => '{{ "included"|e }}',
279+
]));
280+
$policy = new SecurityPolicy([], [], [], [], ['include']);
281+
$sandbox = new SandboxExtension($policy, false);
282+
$twig->addExtension($sandbox);
283+
284+
// The template is loaded without the sandbox enabled
285+
// so, no compile error
286+
$twig->load('included');
287+
288+
// We expect a runtime error
289+
$this->expectException(SecurityError::class);
290+
$twig->render('index');
291+
}
254292
}
255293

256294
final class CoreTestIteratorAggregate implements \IteratorAggregate

0 commit comments

Comments
 (0)
Please sign in to comment.