forked from Wavyzz/dolibarr
Fix #yogosha23433 - Disallow }[ and call_user_func into php code of
website.
This commit is contained in:
@@ -10217,7 +10217,7 @@ function verifCond($strToEvaluate, $onlysimplestring = '1')
|
||||
* '1' (most common use)=Accept only simple string with char 'a-z0-9\s^$_+-.*>&|=!?():"\',/@';',
|
||||
* '2' (used for example for the compute property of extrafields)=Accept also '[]'
|
||||
* @return void|string Nothing or return result of eval (even if type can be int, it is safer to assume string and find all potential typing issues as abs(dol_eval(...)).
|
||||
* @see verifCond()
|
||||
* @see verifCond(), checkPHPCode() to see sanitizing rules that should be very close.
|
||||
* @phan-suppress PhanPluginUnsafeEval
|
||||
*/
|
||||
function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1')
|
||||
@@ -10312,16 +10312,18 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1'
|
||||
}
|
||||
|
||||
// We block use of php exec or php file functions
|
||||
$forbiddenphpstrings = array('$$', '$_');
|
||||
$forbiddenphpstrings = array('$$', '$_', '}[');
|
||||
$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST', 'ReflectionFunction'));
|
||||
|
||||
$forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen");
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_eval", "executeCLI", "verifCond")); // native dolibarr functions
|
||||
$forbiddenphpfunctions = array();
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("base64_decode", "rawurldecode", "urldecode", "str_rot13", "hex2bin")); // decode string functions used to obfuscated function name
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "require", "include", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("override_function", "session_id", "session_create_id", "session_regenerate_id"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("get_defined_functions", "get_defined_vars", "get_defined_constants", "get_declared_classes"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include", "require_once", "include_once"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("exec", "passthru", "shell_exec", "system", "proc_open", "popen"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_eval", "executeCLI", "verifCond")); // native dolibarr functions
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("eval", "create_function", "assert", "mb_ereg_replace")); // function with eval capabilities
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_compress_dir", "dol_decode", "dol_delete_file", "dol_delete_dir", "dol_delete_dir_recursive", "dol_copy", "archiveOrBackupFile")); // more dolibarr functions
|
||||
|
||||
@@ -10339,6 +10341,7 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1'
|
||||
//$s = preg_replace('/\$[a-zA-Z0-9_\->\$]+\(/i', '', $s); // Remove $function( call and $mycall->mymethod(
|
||||
} while ($oldstringtoclean != $s);
|
||||
|
||||
|
||||
if (strpos($s, '__forbiddenstring__') !== false) {
|
||||
dol_syslog('Bad string syntax to evaluate: '.$s, LOG_WARNING);
|
||||
if ($returnvalue) {
|
||||
|
||||
@@ -679,7 +679,7 @@ function showWebsiteTemplates(Website $website)
|
||||
* @param string $phpfullcodestringold PHP old string (before the change). For example "<?php echo 'a' ?><php echo 'b' ?>"
|
||||
* @param string $phpfullcodestring PHP new string. For example "<?php echo 'a' ?><php echo 'c' ?>"
|
||||
* @return int Error or not
|
||||
* @see dolKeepOnlyPhpCode()
|
||||
* @see dolKeepOnlyPhpCode(), dol_eval() to see sanitizing rules that should be very close.
|
||||
*/
|
||||
function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring)
|
||||
{
|
||||
@@ -701,20 +701,46 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring)
|
||||
|
||||
// Then check forbidden commands
|
||||
if (!$error) {
|
||||
$forbiddenphpcommands = array("override_function", "session_id", "session_create_id", "session_regenerate_id");
|
||||
$forbiddenphpstrings = array('$$', '}[');
|
||||
$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('ReflectionFunction'));
|
||||
|
||||
$forbiddenphpfunctions = array();
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("override_function", "session_id", "session_create_id", "session_regenerate_id"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("get_defined_functions", "get_defined_vars", "get_defined_constants", "get_declared_classes"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("call_user_func"));
|
||||
//$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include", "require_once", "include_once"));
|
||||
if (!getDolGlobalString('WEBSITE_PHP_ALLOW_EXEC')) { // If option is not on, we disallow functions to execute commands
|
||||
$forbiddenphpcommands = array_merge($forbiddenphpcommands, array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("exec", "passthru", "shell_exec", "system", "proc_open", "popen"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_eval", "executeCLI", "verifCond")); // native dolibarr functions
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("eval", "create_function", "assert", "mb_ereg_replace")); // function with eval capabilities
|
||||
}
|
||||
if (!getDolGlobalString('WEBSITE_PHP_ALLOW_WRITE')) { // If option is not on, we disallow functions to write files
|
||||
$forbiddenphpcommands = array_merge($forbiddenphpcommands, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "unlink", "mkdir", "rmdir", "symlink", "touch", "umask"));
|
||||
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask"));
|
||||
}
|
||||
foreach ($forbiddenphpcommands as $forbiddenphpcommand) {
|
||||
|
||||
$forbiddenphpmethods = array('invoke', 'invokeArgs'); // Method of ReflectionFunction to execute a function
|
||||
|
||||
foreach ($forbiddenphpstrings as $forbiddenphpstring) {
|
||||
if (preg_match('/'.preg_quote($forbiddenphpstring, '/').'/ms', $phpfullcodestring)) {
|
||||
$error++;
|
||||
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpstring), null, 'errors');
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($forbiddenphpfunctions as $forbiddenphpcommand) {
|
||||
if (preg_match('/'.$forbiddenphpcommand.'\s*\(/ms', $phpfullcodestring)) {
|
||||
$error++;
|
||||
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpcommand), null, 'errors');
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($forbiddenphpmethods as $forbiddenphpmethod) {
|
||||
if (preg_match('/->'.$forbiddenphpmethod.'/ms', $phpfullcodestring)) {
|
||||
$error++;
|
||||
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpmethod), null, 'errors');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This char can be used to execute RCE for example using with echo `ls`
|
||||
|
||||
Reference in New Issue
Block a user