GitHub Security Advisory: GHSA-662m-56v4-3r8f
Package: getgrav/grav (COMPOSER)
Severity: HIGH (CVSS 0.0)
CWE: CWE-94: Improper Control of Generation of Code ('Code Injection'), CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine
Vulnerable versions: < 1.8.0-beta.27
Patched in: 1.8.0-beta.27

Summary: Grav is vulnerable to RCE via SSTI through Twig Sandbox Bypass

Details:
### Summary
A Server-Side Template Injection (SSTI) vulnerability exists in Grav that allows authenticated attackers with editor permissions to execute arbitrary commands on the server and, under certain conditions, may also be exploited by unauthenticated attackers. This vulnerability stems from weak regex validation in the `cleanDangerousTwig` method.

### Important
- First of all this vulnerability is due to weak sanitization in the method `clearDangerousTwig`, so any other class that calls it indirectly through for example `$twig->processString` to sanitize code is also vulnerable.

- For this report, we will need the official Form and Admin plugin installed, also I will be chaining this with another vulnerability to allow an editor which is a user with only pages permissions to edit the process section of a form.

- I made another report for the other vulnerability which is a Broken Access Control which allows a user with full permission for pages to change the process section by intercepting the request and modifying it.

### Permissions Needed
- The main case for this vulnerability is an editor which can unconditionally takeover the whole system through creating a vulnerable form.
- Second case is as an unauthenticated user, so if the form exists already and accepts user input and puts it through `evaluate_twig`, a guest can takeover the system.

### Details
When we make a form with a process section and a `message` action, when the form is submitted we get to deal with `onFormProcess` in `form.php` through the `message` case:

```php
            case 'message':
                $translated_string = $this->grav['language']->translate($params);
                $vars = array(
                    'form' => $form
                );

                /** @var Twig $twig */
                $twig = $this->grav['twig'];
                $processed_string = $twig->processString($translated_string, $vars);

                $form->message = $processed_string;
                break;
```

Which takes our parameters as in our action values, like in our case the value of our `message` action and sends it to `processString` which then calls the method `cleanDangerousTwig` from `Security.php`, now here's where we find the vulnerability is caused by two things:

- First of all is weak regex which doesn't account for nested function calls, which allows us to bypass this function's sanitization
- Second issue which is the `evaluate` and `evaluate_twig` functions which are allowed, and since we can call Twig syntax from inside them, it will lead to nested function calls which we can bypass and thus execute arbitrary payloads.

```php
    public static function cleanDangerousTwig(string $string): string
    {
        if ($string === '') {
            return $string;
        }

        $bad_twig = [
            'twig_array_map',
            'twig_array_filter',
            'call_user_func',
            'registerUndefinedFunctionCallback',
            'undefined_fun