From 79283c6f7f0365a40737f488f0aa64a0a04e784e Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 12 Jun 2022 10:44:00 +0300 Subject: [PATCH 1/2] Fix `Fenom::isAllowedFunction()` - Checks if function in `ini_get('disable_functions')` - Replace `is_callable()` to `function_exists()` to ignore invokable classes --- src/Fenom.php | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Fenom.php b/src/Fenom.php index bdc789d..4c6ad7c 100644 --- a/src/Fenom.php +++ b/src/Fenom.php @@ -200,6 +200,11 @@ class Fenom "implode" => 1 ); + /** + * @var string[] the disabled functions by `disable_functions` PHP's option + */ + protected $_disabled_funcs; + /** * @var array[] of compilers and functions */ @@ -769,16 +774,24 @@ class Fenom } /** - * @param string $function + * Checks if is allowed PHP function for using in templates. + * + * @param string $function the function name * @return bool */ public function isAllowedFunction($function) { - if ($this->_options & self::DENY_NATIVE_FUNCS) { - return isset($this->_allowed_funcs[$function]); - } else { - return is_callable($function); + $function = (string) $function; + if (!is_array($this->_disabled_funcs)) { + $disabled = ini_get('disable_functions'); + $this->_disabled_funcs = empty($disabled) ? [] : explode(',', $disabled); } + + if ($this->_options & self::DENY_NATIVE_FUNCS) { + return isset($this->_allowed_funcs[$function]) && !in_array($function, $this->_disabled_funcs, true); + } + + return function_exists($function) && !in_array($function, $this->_disabled_funcs, true); } /** From 5e14c6bf90e87da9cd6c9fa6bde17f314ace05ee Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 12 Jun 2022 11:46:43 +0300 Subject: [PATCH 2/2] Update Fenom.php --- src/Fenom.php | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Fenom.php b/src/Fenom.php index 4c6ad7c..f8603ad 100644 --- a/src/Fenom.php +++ b/src/Fenom.php @@ -782,16 +782,30 @@ class Fenom public function isAllowedFunction($function) { $function = (string) $function; + $allow = ($this->_options & self::DENY_NATIVE_FUNCS) + ? isset($this->_allowed_funcs[$function]) + : function_exists($function); + return $allow && !in_array($function, $this->getDisabledFuncs(), true); + } + + /** + * Returns the disabled PHP functions. + * + * @return string[] + */ + protected function _getDisabledFuncs() + { if (!is_array($this->_disabled_funcs)) { $disabled = ini_get('disable_functions'); - $this->_disabled_funcs = empty($disabled) ? [] : explode(',', $disabled); + // adds execution functions to disabled for security + $this->_disabled_funcs = array_merge( + empty($disabled) ? [] : explode(',', $disabled), + array('exec', 'system', 'passthru', 'shell_exec', 'pcntl_exec', 'proc_open', 'popen'), + array('call_user_func', 'call_user_func_array') + ); } - if ($this->_options & self::DENY_NATIVE_FUNCS) { - return isset($this->_allowed_funcs[$function]) && !in_array($function, $this->_disabled_funcs, true); - } - - return function_exists($function) && !in_array($function, $this->_disabled_funcs, true); + return $this->_disabled_funcs; } /**