VYPR
High severityNVD Advisory· Published Jun 14, 2023· Updated Dec 18, 2024

Grav Server-side Template Injection via Insufficient Validation in filterFilter

CVE-2023-34252

Description

Grav is a flat-file content management system. Prior to version 1.7.42, there is a logic flaw in the GravExtension.filterFilter() function whereby validation against a denylist of unsafe functions is only performed when the argument passed to filter is a string. However, passing an array as a callable argument allows the validation check to be skipped. Consequently, a low privileged attacker with login access to Grav Admin panel and page creation/update permissions is able to inject malicious templates to obtain remote code execution. The vulnerability can be found in the GravExtension.filterFilter() function declared in /system/src/Grav/Common/Twig/Extension/GravExtension.php. Version 1.7.42 contains a patch for this issue. End users should also ensure that twig.undefined_functions and twig.undefined_filters properties in /path/to/webroot/system/config/system.yaml configuration file are set to false to disallow Twig from treating undefined filters/functions as PHP functions and executing them.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
getgrav/gravPackagist
< 1.7.421.7.42

Affected products

1

Patches

4
244758d43830

also handle SSTI in reduce twig filter + function

https://github.com/getgrav/gravAndy MillerJun 14, 2023via ghsa
2 files changed · +29 6
  • CHANGELOG.md+2 1 modified
    @@ -4,10 +4,11 @@
     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`
    +   * 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
    
  • system/src/Grav/Common/Twig/Extension/GravExtension.php+27 5 modified
    @@ -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,12 +1728,28 @@ 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.');
             }
     
             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);
    +    }
     }
    
71bbed12f950

more SSTI fixes in Utils::isDangerousFunction()

https://github.com/getgrav/gravAndy MillerJun 13, 2023via ghsa
2 files changed · +18 1
  • CHANGELOG.md+1 0 modified
    @@ -5,6 +5,7 @@
        * 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`
    +   * Various SSTI improvements `Utils::isDangerousFunction()`
     1. [](#bugfix)
        * Fixed Twig `|map()` allowing code execution
     
    
  • system/src/Grav/Common/Utils.php+17 1 modified
    @@ -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;
             }
    
8c2c1cb72611

better SSTI in |map and |filter

https://github.com/getgrav/gravAndy MillerJun 13, 2023via ghsa
3 files changed · +11 5
  • CHANGELOG.md+3 1 modified
    @@ -3,8 +3,10 @@
     
     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
    
  • system/src/Grav/Common/Twig/Extension/GravExtension.php+2 2 modified
    @@ -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.');
             }
     
    
  • system/src/Grav/Common/Utils.php+6 2 modified
    @@ -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;
             }
    
9d01140a63c7

Fix for dangerous tags in |map filter

https://github.com/getgrav/gravAndy MillerJun 13, 2023via ghsa
2 files changed · +19 0
  • CHANGELOG.md+2 0 modified
    @@ -3,6 +3,8 @@
     
     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. [](#bugfix)
    +   * * Fixed Twig `|map()` allowing code execution
     
     # v1.7.41.2
     ## 06/01/2023
    
  • system/src/Grav/Common/Twig/Extension/GravExtension.php+17 0 modified
    @@ -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);
    +    }
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.