CVE-2023-34448: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: Grav is a flat-file content management system. Prior to version 1.7.42, the patch for CVE-2022-2073, a server-side template injection vulnerability in Grav leveraging the default `filter()` function, did not block other built-in functions exposed by Twig's Core Extension that could be used to invoke arbitrary unsafe functions, thereby allowing for remote code execution. A patch in version 1.74.2 overrides the built-in Twig `map()` and `reduce()` filter functions in `system/src/Grav/Common/Twig/Extension/GravExtension.php` to validate the argument passed to the filter in `$arrow`.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 7.2
Published: 2023-06-14T23:15Z
Repository: https://github.com/getgrav/grav
Language: PHP
Files changed: CHANGELOG.md, system/src/Grav/Common/Twig/Extension/GravExtension.php, system/src/Grav/Common/Utils.php
Commit date: 2023-06-13 17:45:40 -0600
Commit message: better SSTI in |map and |filter

Diff: diff --git a/CHANGELOG.md b/CHANGELOG.md
index ab837d5e00..b5d69dcfeb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,14 @@
 # v1.7.42
 ## mm/dd/2023
 
 1. [](#new)
    * Added a new `system.languages.debug` option that adds a `<span class="translate-debug"></span>` 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
 
 1. [](#improved)
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
@@ -1706,11 +1706,11 @@ class GravExtension extends AbstractExtension implements GlobalsInterface
      * @return array|CallbackFilterIterator
      * @throws RuntimeError
      */
     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.');
         }
 
         return twig_array_filter($env, $array, $arrow);
     }
@@ -1722,11 +1722,11 @@ class GravExtension extends AbstractExtension implements GlobalsInterface
      * @return array|CallbackFilterIterator
      * @throws RuntimeError
      */
     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.');
         }
 
         return twig_array_map($env, $array, $arrow);
     }
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
@@ -1948,14 +1948,14 @@ abstract class Utils
 
         return $types;
     }
 
     /**
-     * @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',
             'passthru',
             'system',
@@ -2048,10 +2048,14 @@ abstract class Utils
             'posix_setpgid',
             'posix_setsid',
             'posix_setuid',
         ];
 
+        if (is_array($name) || strpos($name, ":") !== false) {
+            return false;
+        }
+
         if (in_array($name, $commandExecutionFunctions)) {
             return true;
         }
 
         if (in_array($name, $codeExecutionFunctions)) {

Vulnerable code:    * * Fixed Twig `|map()` allowing code execution
        if (is_string($arrow) && Utils::isDangerousFunction($arrow)) {
        if (is_string($arrow) && Utils::isDangerousFunction($arrow)) {
     * @param string $name
    public static function isDangerousFunction(string $name): bool
Fixed code: 1. [](#improved)
   * More robust SSTI handling in `|filter` and `|map`
   * Fixed Twig `|map()` allowing code execution
        if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) {
        if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) {
     * @param string|array $name
    public static function isDangerousFunction($name): bool
        if (is_array($name) || strpos($name, ":") !== false) {
            return false;
        }