Skip to content

Commit 9e5ca74

Browse files
committed
Merge branch '2.x' into 3.x
* 2.x: Disallow non closures in `sort` filter when the sanbox mode is enabled
2 parents 25d410b + 22b9dc3 commit 9e5ca74

File tree

3 files changed

+16
-13
lines changed

3 files changed

+16
-13
lines changed

CHANGELOG

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 3.3.8 (2022-XX-XX)
22

3-
* n/a
3+
* Fix a security issue when in a sandbox: the `sort` filter must require a Closure for the `arrow` parameter
44

55
# 3.3.7 (2022-01-03)
66

src/Extension/CoreExtension.php

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public function getFilters(): array
201201
// array helpers
202202
new TwigFilter('join', 'twig_join_filter'),
203203
new TwigFilter('split', 'twig_split_filter', ['needs_environment' => true]),
204-
new TwigFilter('sort', 'twig_sort_filter'),
204+
new TwigFilter('sort', 'twig_sort_filter', ['needs_environment' => true]),
205205
new TwigFilter('merge', 'twig_array_merge'),
206206
new TwigFilter('batch', 'twig_array_batch'),
207207
new TwigFilter('column', 'twig_array_column'),
@@ -887,7 +887,7 @@ function twig_reverse_filter(Environment $env, $item, $preserveKeys = false)
887887
*
888888
* @return array
889889
*/
890-
function twig_sort_filter($array, $arrow = null)
890+
function twig_sort_filter(Environment $env, $array, $arrow = null)
891891
{
892892
if ($array instanceof \Traversable) {
893893
$array = iterator_to_array($array);
@@ -896,6 +896,8 @@ function twig_sort_filter($array, $arrow = null)
896896
}
897897

898898
if (null !== $arrow) {
899+
twig_check_arrow_in_sandbox($env, $arrow, 'sort', 'filter');
900+
899901
uasort($array, $arrow);
900902
} else {
901903
asort($array);
@@ -1639,9 +1641,7 @@ function twig_array_filter(Environment $env, $array, $arrow)
16391641
throw new RuntimeError(sprintf('The "filter" filter expects an array or "Traversable", got "%s".', \is_object($array) ? \get_class($array) : \gettype($array)));
16401642
}
16411643

1642-
if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
1643-
throw new RuntimeError('The callable passed to "filter" filter must be a Closure in sandbox mode.');
1644-
}
1644+
twig_check_arrow_in_sandbox($env, $arrow, 'filter', 'filter');
16451645

16461646
if (\is_array($array)) {
16471647
return array_filter($array, $arrow, \ARRAY_FILTER_USE_BOTH);
@@ -1653,9 +1653,7 @@ function twig_array_filter(Environment $env, $array, $arrow)
16531653

16541654
function twig_array_map(Environment $env, $array, $arrow)
16551655
{
1656-
if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
1657-
throw new RuntimeError('The callable passed to the "map" filter must be a Closure in sandbox mode.');
1658-
}
1656+
twig_check_arrow_in_sandbox($env, $arrow, 'map', 'filter');
16591657

16601658
$r = [];
16611659
foreach ($array as $k => $v) {
@@ -1667,9 +1665,7 @@ function twig_array_map(Environment $env, $array, $arrow)
16671665

16681666
function twig_array_reduce(Environment $env, $array, $arrow, $initial = null)
16691667
{
1670-
if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
1671-
throw new RuntimeError('The callable passed to the "reduce" filter must be a Closure in sandbox mode.');
1672-
}
1668+
twig_check_arrow_in_sandbox($env, $arrow, 'reduce', 'filter');
16731669

16741670
if (!\is_array($array)) {
16751671
if (!$array instanceof \Traversable) {
@@ -1681,4 +1677,11 @@ function twig_array_reduce(Environment $env, $array, $arrow, $initial = null)
16811677

16821678
return array_reduce($array, $arrow, $initial);
16831679
}
1680+
1681+
function twig_check_arrow_in_sandbox(Environment $env, $arrow, $thing, $type)
1682+
{
1683+
if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
1684+
throw new RuntimeError(sprintf('The callable passed to the "%s" %s must be a Closure in sandbox mode.', $thing, $type));
1685+
}
1686+
}
16841687
}

tests/Extension/SandboxTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ public function testSandboxDisabledAfterIncludeFunctionError()
390390
public function testSandboxWithNoClosureFilter()
391391
{
392392
$this->expectException('\Twig\Error\RuntimeError');
393-
$this->expectExceptionMessage('The callable passed to "filter" filter must be a Closure in sandbox mode in "index" at line 1.');
393+
$this->expectExceptionMessage('The callable passed to the "filter" filter must be a Closure in sandbox mode in "index" at line 1.');
394394

395395
$twig = $this->getEnvironment(true, ['autoescape' => 'html'], ['index' => <<<EOF
396396
{{ ["foo", "bar", ""]|filter("trim")|join(", ") }}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy