CVE-2020-28925 (PHP, published 2020-12-30T19:15Z)
Description: value: Bolt before 3.7.2 does not restrict filter options in a Request in the Twig context, and is therefore inconsistent with the "How to Harden Your PHP for Better Security" guidance.
Severity: MEDIUM (CVSS v3 base score: 5.3)
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/bolt/bolt
Files changed:
src/Twig/ArrayAccessSecurityProxy.php
src/Twig/Request/FileBag.php
src/Twig/Request/ParameterBag.php
src/Twig/Request/RestrictedFilterTrait.php
src/Twig/Request/ServerBag.php
Commit message: Restrict `filter` options in `Request` in Twig context


Vulnerable code:

Fixed code:
        if ($offset === 'request') {
            $request = $this->object[$offset];

            $request->request = new Request\ParameterBag($request->request->all());
            $request->query = new Request\ParameterBag($request->query->all());
            $request->attributes = new Request\ParameterBag($request->attributes->all());
            $request->cookies = new Request\ParameterBag($request->cookies->all());
            $request->files = new Request\FileBag($request->files->all());
            $request->server = new Request\ServerBag($request->server->all());

            return $request;
        }

<?php

namespace Bolt\Twig\Request;

/**
 * ParameterBag is a container for key/value pairs.
 * Overridden in order to disable certain filters.
 *
 * @author Xiao-Hu Tai <xiao@twokings.nl>
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FileBag extends \Symfony\Component\HttpFoundation\FileBag implements \IteratorAggregate, \Countable
{
    use RestrictedFilterTrait;
}
<?php

namespace Bolt\Twig\Request;

/**
 * ParameterBag is a container for key/value pairs.
 * Overridden in order to disable certain filters.
 *
 * @author Xiao-Hu Tai <xiao@twokings.nl>
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ParameterBag extends \Symfony\Component\HttpFoundation\ParameterBag implements \IteratorAggregate, \Countable
{
    use RestrictedFilterTrait;
}
<?php

namespace Bolt\Twig\Request;

/**
 * Override filter function in order to restrict certain options in Twig context.
 * The list of restricted options are taken from "How to Harden Your PHP for
 * Better Security" [1].
 *
 * [1] https://howtogetonline.com/how-to-harden-your-php-for-better-security.php
 *
 * @author Xiao-Hu Tai <xiao@twokings.nl>
 */
trait RestrictedFilterTrait
{
    /** @var array */
    private $restrictedOptions = [
        '_getppid',
        'allow_url_fopen',
        'allow_url_include',
        'chgrp',
        'chmod',
        'chown',
        'curl_exec',
        'curl_multi_exec',
        'diskfreespace',
        'dl',
        'exec',
        'fpaththru',
        'getmypid',
        'getmyuid',
        'highlight_file',
        'ignore_user_abord',
        'ini_set',
        'lchgrp',
        'lchown',
        'leak',
        'link',
        'listen',
        'parse_ini_file',
        'passthru',
        'pcntl_exec',
        'php_uname',
        'phpinfo',
        'popen',
        'posix_ctermid',
        'posix_getcwd',
        'posix_getegid',
        'posix_geteuid',
        'posix_getgid',
        'posix_getgrgid',
        'posix_getgrnam',
        'posix_getgroups',
        'posix_getlogin',
        'posix_getpgid',
        'posix_getpgrp',
        'posix_getpid',
        'posix_getpwnam',
        'posix_getpwuid',
        'posix_getrlimit',
        'posix_getsid',
        'posix_getuid',
        'posix_isatty',
        'posix_kill',
        'posix_mkfifo',
        'posix_setegid',
        'posix_seteuid',
        'posix_setgid',
        'posix_setpgid',
        'posix_setsid',
        'posix_setuid',
        'posix_times',
        'posix_ttyname',
        'posix_uname',
        'posix',
        'proc_close',
        'proc_get_status',
        'proc_nice',
        'proc_open',
        'proc_terminate',
        'putenv',
        'set_time_limit',
        'shell_exec',
        'show_source',
        'source',
        'system',
        'tmpfile',
        'virtual',
    ];

    /**
     * {@inheritdoc}
     */
    public function filter($key, $default = null, $filter = FILTER_DEFAULT, $options = array(), $deep = false)
    {
        if (isset($options['options']) && in_array($options['options'], $this->restrictedOptions)) {
            unset($options['options']);
        }

        return parent::filter($key, $default, $filter, $options, $deep);
    }
}
<?php

namespace Bolt\Twig\Request;

/**
 * ParameterBag is a container for key/value pairs.
 * Overridden in order to disable certain filters.
 *
 * @author Xiao-Hu Tai <xiao@twokings.nl>
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ServerBag extends \Symfony\Component\HttpFoundation\ServerBag implements \IteratorAggregate, \Countable
{
    use RestrictedFilterTrait;
}