From 259e775db84b690dc43f0fa981dbdfc822c9d8bc Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 8 Jun 2023 14:50:52 -0600 Subject: [PATCH 1/6] Added languages debug option --- CHANGELOG.md | 6 ++++++ system/blueprints/config/system.yaml | 11 +++++++++++ system/config/system.yaml | 1 + .../src/Grav/Common/Twig/Extension/GravExtension.php | 10 ++++++++-- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7956dc3b02..62bfeb483c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v1.7.42 +## mm/dd/2023 + +1. [](#new) + * Added a new `system.languages.debug` option that adds a `` around strings translated with `|t`. This can be styled by the theme as needed. + # v1.7.41.2 ## 06/01/2023 diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 14fef03ce9..182457cbbd 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -448,6 +448,17 @@ form: validate: type: bool + languages.debug: + type: toggle + label: PLUGIN_ADMIN.LANGUAGE_DEBUG + help: PLUGIN_ADMIN.LANGUAGE_DEBUG_HELP + highlight: 0 + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO + validate: + type: bool + http_headers: type: tab title: PLUGIN_ADMIN.HTTP_HEADERS diff --git a/system/config/system.yaml b/system/config/system.yaml index 2ffd02a8c9..8bcc280758 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -28,6 +28,7 @@ languages: override_locale: false # Override the default or system locale with language specific one content_fallback: {} # Custom language fallbacks. eg: {fr: ['fr', 'en']} pages_fallback_only: false # DEPRECATED: Use `content_fallback` instead + debug: false # Debug language detection home: alias: '/home' # Default path for home, ie / diff --git a/system/src/Grav/Common/Twig/Extension/GravExtension.php b/system/src/Grav/Common/Twig/Extension/GravExtension.php index 9f54a1733d..cfadb0417a 100644 --- a/system/src/Grav/Common/Twig/Extension/GravExtension.php +++ b/system/src/Grav/Common/Twig/Extension/GravExtension.php @@ -46,6 +46,7 @@ use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; use Twig\Loader\FilesystemLoader; +use Twig\Markup; use Twig\TwigFilter; use Twig\TwigFunction; use function array_slice; @@ -905,8 +906,13 @@ public function translate(Environment $twig, ...$args) return $this->grav['admin']->translate($args, $lang); } - // else use the default grav translate functionality - return $this->grav['language']->translate($args); + $translation = $this->grav['language']->translate($args); + + if ($this->config->get('system.languages.debug', false)) { + return new Markup("$translation", 'UTF-8'); + } else { + return $translation; + } } /** From 9d01140a63c77075ef09b26ef57cf186138151a5 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 13 Jun 2023 17:07:39 -0600 Subject: [PATCH 2/6] Fix for dangerous tags in |map filter --- CHANGELOG.md | 2 ++ .../Common/Twig/Extension/GravExtension.php | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62bfeb483c..ab837d5e00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 1. [](#new) * Added a new `system.languages.debug` option that adds a `` around strings translated with `|t`. This can be styled by the theme as needed. +1. [](#bugfix) + * * Fixed Twig `|map()` allowing code execution # v1.7.41.2 ## 06/01/2023 diff --git a/system/src/Grav/Common/Twig/Extension/GravExtension.php b/system/src/Grav/Common/Twig/Extension/GravExtension.php index cfadb0417a..b4f5d70eaa 100644 --- a/system/src/Grav/Common/Twig/Extension/GravExtension.php +++ b/system/src/Grav/Common/Twig/Extension/GravExtension.php @@ -173,6 +173,7 @@ public function getFilters(): array // Security fix new TwigFilter('filter', [$this, 'filterFilter'], ['needs_environment' => true]), + new TwigFilter('map', [$this, 'mapFilter'], ['needs_environment' => true]), ]; } @@ -1713,4 +1714,20 @@ function filterFilter(Environment $env, $array, $arrow) return twig_array_filter($env, $array, $arrow); } + + /** + * @param Environment $env + * @param array $array + * @param callable|string $arrow + * @return array|CallbackFilterIterator + * @throws RuntimeError + */ + function mapFilter(Environment $env, $array, $arrow) + { + if (is_string($arrow) && Utils::isDangerousFunction($arrow)) { + throw new RuntimeError('Twig |map("' . $arrow . '") is not allowed.'); + } + + return twig_array_map($env, $array, $arrow); + } } From 8c2c1cb72611a399f13423fc6d0e1d998c03e5c8 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 13 Jun 2023 17:45:40 -0600 Subject: [PATCH 3/6] better SSTI in |map and |filter --- CHANGELOG.md | 4 +++- system/src/Grav/Common/Twig/Extension/GravExtension.php | 4 ++-- system/src/Grav/Common/Utils.php | 8 ++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab837d5e00..b5d69dcfeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,10 @@ 1. [](#new) * Added a new `system.languages.debug` option that adds a `` around strings translated with `|t`. This can be styled by the theme as needed. +1. [](#improved) + * More robust SSTI handling in `|filter` and `|map` 1. [](#bugfix) - * * Fixed Twig `|map()` allowing code execution + * Fixed Twig `|map()` allowing code execution # v1.7.41.2 ## 06/01/2023 diff --git a/system/src/Grav/Common/Twig/Extension/GravExtension.php b/system/src/Grav/Common/Twig/Extension/GravExtension.php index b4f5d70eaa..daddc9106d 100644 --- a/system/src/Grav/Common/Twig/Extension/GravExtension.php +++ b/system/src/Grav/Common/Twig/Extension/GravExtension.php @@ -1708,7 +1708,7 @@ public function ofTypeFunc($var, $typeTest = null, $className = null) */ function filterFilter(Environment $env, $array, $arrow) { - if (is_string($arrow) && Utils::isDangerousFunction($arrow)) { + if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { throw new RuntimeError('Twig |filter("' . $arrow . '") is not allowed.'); } @@ -1724,7 +1724,7 @@ function filterFilter(Environment $env, $array, $arrow) */ function mapFilter(Environment $env, $array, $arrow) { - if (is_string($arrow) && Utils::isDangerousFunction($arrow)) { + if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { throw new RuntimeError('Twig |map("' . $arrow . '") is not allowed.'); } diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index cadb787189..24a7417797 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -1950,10 +1950,10 @@ public static function getSupportPageTypes(array $defaults = null) } /** - * @param string $name + * @param string|array $name * @return bool */ - public static function isDangerousFunction(string $name): bool + public static function isDangerousFunction($name): bool { static $commandExecutionFunctions = [ 'exec', @@ -2050,6 +2050,10 @@ public static function isDangerousFunction(string $name): bool 'posix_setuid', ]; + if (is_array($name) || strpos($name, ":") !== false) { + return false; + } + if (in_array($name, $commandExecutionFunctions)) { return true; } From 71bbed12f950de8335006d7f91112263d8504f1b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 13 Jun 2023 17:57:11 -0600 Subject: [PATCH 4/6] more SSTI fixes in Utils::isDangerousFunction() --- CHANGELOG.md | 1 + system/src/Grav/Common/Utils.php | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d69dcfeb..a3c5934046 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Added a new `system.languages.debug` option that adds a `` around strings translated with `|t`. This can be styled by the theme as needed. 1. [](#improved) * More robust SSTI handling in `|filter` and `|map` + * Various SSTI improvements `Utils::isDangerousFunction()` 1. [](#bugfix) * Fixed Twig `|map()` allowing code execution diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 24a7417797..14748a558d 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -1950,7 +1950,7 @@ public static function getSupportPageTypes(array $defaults = null) } /** - * @param string|array $name + * @param string|array|Closure $name * @return bool */ public static function isDangerousFunction($name): bool @@ -2048,8 +2048,24 @@ public static function isDangerousFunction($name): bool 'posix_setpgid', 'posix_setsid', 'posix_setuid', + 'unserialize', + 'ini_alter', + 'simplexml_load_file', + 'simplexml_load_string', + 'forward_static_call', + 'forward_static_call_array', ]; + $name = strtolower($name); + + if ($name instanceof \Closure) { + return false; + } + + if (strpos($name, "\\") !== false) { + return false; + } + if (is_array($name) || strpos($name, ":") !== false) { return false; } From 244758d4383034fe4cd292d41e477177870b65ec Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 14 Jun 2023 11:08:17 -0600 Subject: [PATCH 5/6] also handle SSTI in reduce twig filter + function --- CHANGELOG.md | 3 +- .../Common/Twig/Extension/GravExtension.php | 32 ++++++++++++++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3c5934046..cef87dd840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,11 @@ 1. [](#new) * Added a new `system.languages.debug` option that adds a `` around strings translated with `|t`. This can be styled by the theme as needed. 1. [](#improved) - * More robust SSTI handling in `|filter` and `|map` + * More robust SSTI handling in `filter`, `map`, and `reduce` Twig filters and functions * Various SSTI improvements `Utils::isDangerousFunction()` 1. [](#bugfix) * Fixed Twig `|map()` allowing code execution + * Fixed Twig `|reduce()` allowing code execution # v1.7.41.2 ## 06/01/2023 diff --git a/system/src/Grav/Common/Twig/Extension/GravExtension.php b/system/src/Grav/Common/Twig/Extension/GravExtension.php index daddc9106d..2ef5364a38 100644 --- a/system/src/Grav/Common/Twig/Extension/GravExtension.php +++ b/system/src/Grav/Common/Twig/Extension/GravExtension.php @@ -171,9 +171,10 @@ public function getFilters(): array new TwigFilter('count', 'count'), new TwigFilter('array_diff', 'array_diff'), - // Security fix - new TwigFilter('filter', [$this, 'filterFilter'], ['needs_environment' => true]), - new TwigFilter('map', [$this, 'mapFilter'], ['needs_environment' => true]), + // Security fixes + new TwigFilter('filter', [$this, 'filterFunc'], ['needs_environment' => true]), + new TwigFilter('map', [$this, 'mapFunc'], ['needs_environment' => true]), + new TwigFilter('reduce', [$this, 'reduceFunc'], ['needs_environment' => true]), ]; } @@ -250,6 +251,11 @@ public function getFunctions(): array new TwigFunction('count', 'count'), new TwigFunction('array_diff', 'array_diff'), new TwigFunction('parse_url', 'parse_url'), + + // Security fixes + new TwigFunction('filter', [$this, 'filterFunc'], ['needs_environment' => true]), + new TwigFunction('map', [$this, 'mapFunc'], ['needs_environment' => true]), + new TwigFunction('reduce', [$this, 'reduceFunc'], ['needs_environment' => true]), ]; } @@ -1706,7 +1712,7 @@ public function ofTypeFunc($var, $typeTest = null, $className = null) * @return array|CallbackFilterIterator * @throws RuntimeError */ - function filterFilter(Environment $env, $array, $arrow) + function filterFunc(Environment $env, $array, $arrow) { if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { throw new RuntimeError('Twig |filter("' . $arrow . '") is not allowed.'); @@ -1722,7 +1728,7 @@ function filterFilter(Environment $env, $array, $arrow) * @return array|CallbackFilterIterator * @throws RuntimeError */ - function mapFilter(Environment $env, $array, $arrow) + function mapFunc(Environment $env, $array, $arrow) { if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { throw new RuntimeError('Twig |map("' . $arrow . '") is not allowed.'); @@ -1730,4 +1736,20 @@ function mapFilter(Environment $env, $array, $arrow) return twig_array_map($env, $array, $arrow); } + + /** + * @param Environment $env + * @param array $array + * @param callable|string $arrow + * @return array|CallbackFilterIterator + * @throws RuntimeError + */ + function reduceFunc(Environment $env, $array, $arrow) + { + if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { + throw new RuntimeError('Twig |reduce("' . $arrow . '") is not allowed.'); + } + + return twig_array_map($env, $array, $arrow); + } } From 50ee844759c3d0f882f7e635764749d901555451 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 14 Jun 2023 14:19:00 -0600 Subject: [PATCH 6/6] prepare for release --- CHANGELOG.md | 2 +- system/defines.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cef87dd840..50aca24d3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v1.7.42 -## mm/dd/2023 +## 06/14/2023 1. [](#new) * Added a new `system.languages.debug` option that adds a `` around strings translated with `|t`. This can be styled by the theme as needed. diff --git a/system/defines.php b/system/defines.php index 02b37c9010..634cb524ae 100644 --- a/system/defines.php +++ b/system/defines.php @@ -9,7 +9,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.7.41.2'); +define('GRAV_VERSION', '1.7.42'); define('GRAV_SCHEMA', '1.7.0_2020-11-20_1'); define('GRAV_TESTING', false);