diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index d0034b2de59..9e8a6ec0e18 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -328,7 +328,7 @@ function run_sql($sqlfile, $silent = 1, $entity = 0, $usesavepoint = 1, $handler $keyforsql = md5($sqlfile); foreach ($arraysql as $i => $sql) { if ($sql) { - // Test if th SQL is allowed SQL + // Test if the SQL is allowed SQL if ($onlysqltoimportwebsite) { $newsql = str_replace(array("\'"), '__BACKSLASHQUOTE__', $sql); // Replace the \' char @@ -388,6 +388,7 @@ function run_sql($sqlfile, $silent = 1, $entity = 0, $usesavepoint = 1, $handler break; } + if (!$qualified) { $error++; //print 'Request '.($i + 1)." contains non allowed instructions.
\n"; diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 00de177fd58..2ba2f9ae4b9 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -681,49 +681,55 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) return 0; } - // First check forbidden commands - $forbiddenphpcommands = array("override_function", "session_id", "session_create_id", "session_regenerate_id"); - 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")); - } - 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")); - } - foreach ($forbiddenphpcommands as $forbiddenphpcommand) { - if (preg_match('/'.$forbiddenphpcommand.'\s*\(/ms', $phpfullcodestring)) { - $error++; - setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpcommand), null, 'errors'); - break; - } - } - // This char can be used to execute RCE for example using with echo `ls` - $forbiddenphpchars = array(); - if (!getDolGlobalString('WEBSITE_PHP_ALLOW_DANGEROUS_CHARS')) { // If option is not on, we disallow functions to execute commands - $forbiddenphpchars = array("`"); - } - foreach ($forbiddenphpchars as $forbiddenphpchar) { - if (preg_match('/'.$forbiddenphpchar.'/ms', $phpfullcodestring)) { - $error++; - setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpchar), null, 'errors'); - break; - } - } - // Deny dynamic functions '${a}(' or '$a[b](' - So we refuse '}(' and '](' - if (preg_match('/[}\]]\(/ims', $phpfullcodestring)) { - $error++; - setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", ']('), null, 'errors'); - } - // Deny dynamic functions $xxx( - if (preg_match('/\$[a-z0-9_]+\(/ims', $phpfullcodestring)) { - $error++; - setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", '$...('), null, 'errors'); - } - + // First check permission if ($phpfullcodestringold != $phpfullcodestring) { if (!$error && !$user->hasRight('website', 'writephp')) { $error++; setEventMessages($langs->trans("NotAllowedToAddDynamicContent"), null, 'errors'); } + } + + // Then check forbidden commands + if (!$error) { + $forbiddenphpcommands = array("override_function", "session_id", "session_create_id", "session_regenerate_id"); + 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")); + } + 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")); + } + foreach ($forbiddenphpcommands as $forbiddenphpcommand) { + if (preg_match('/'.$forbiddenphpcommand.'\s*\(/ms', $phpfullcodestring)) { + $error++; + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpcommand), null, 'errors'); + break; + } + } + // This char can be used to execute RCE for example using with echo `ls` + $forbiddenphpchars = array(); + if (!getDolGlobalString('WEBSITE_PHP_ALLOW_DANGEROUS_CHARS')) { // If option is not on, we disallow functions to execute commands + $forbiddenphpchars = array("`"); + } + foreach ($forbiddenphpchars as $forbiddenphpchar) { + if (preg_match('/'.$forbiddenphpchar.'/ms', $phpfullcodestring)) { + $error++; + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpchar), null, 'errors'); + break; + } + } + // Deny dynamic functions '${a}(' or '$a[b](' - So we refuse '}(' and '](' + if (preg_match('/[}\]]\(/ims', $phpfullcodestring)) { + $error++; + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", ']('), null, 'errors'); + } + // Deny dynamic functions $xxx( + if (preg_match('/\$[a-z0-9_]+\(/ims', $phpfullcodestring)) { + $error++; + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", '$...('), null, 'errors'); + } + } + + if ($phpfullcodestringold != $phpfullcodestring) { if (!$error) { $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT); $allowimportsite = true;