Skip to content

Commit

Permalink
Merge branch 'release/1.7.42'
Browse files Browse the repository at this point in the history
  • Loading branch information
rhukster committed Jun 14, 2023
2 parents d4c617f + 50ee844 commit dc20945
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 9 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# v1.7.42
## 06/14/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`, `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

Expand Down
11 changes: 11 additions & 0 deletions system/blueprints/config/system.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions system/config/system.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 /
Expand Down
2 changes: 1 addition & 1 deletion system/defines.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
57 changes: 51 additions & 6 deletions system/src/Grav/Common/Twig/Extension/GravExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -170,8 +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]),
// 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]),
];
}

Expand Down Expand Up @@ -248,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]),
];
}

Expand Down Expand Up @@ -905,8 +913,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("<span class=\"translate-debug\" data-toggle=\"tooltip\" title=\"" . $args[0] . "\">$translation</span>", 'UTF-8');
} else {
return $translation;
}
}

/**
Expand Down Expand Up @@ -1699,12 +1712,44 @@ 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 (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);
}

/**
* @param Environment $env
* @param array $array
* @param callable|string $arrow
* @return array|CallbackFilterIterator
* @throws RuntimeError
*/
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);
}
}
24 changes: 22 additions & 2 deletions system/src/Grav/Common/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -1950,10 +1950,10 @@ public static function getSupportPageTypes(array $defaults = null)
}

/**
* @param string $name
* @param string|array|Closure $name
* @return bool
*/
public static function isDangerousFunction(string $name): bool
public static function isDangerousFunction($name): bool
{
static $commandExecutionFunctions = [
'exec',
Expand Down Expand Up @@ -2048,8 +2048,28 @@ public static function isDangerousFunction(string $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;
}

if (in_array($name, $commandExecutionFunctions)) {
return true;
}
Expand Down

0 comments on commit dc20945

Please sign in to comment.