Fix #yogosha9033
This commit is contained in:
parent
82250fae62
commit
eede3aaf17
@ -601,3 +601,59 @@ function showWebsiteTemplates(Website $website)
|
|||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
print '</table>';
|
print '</table>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checkPHPCode
|
||||||
|
*
|
||||||
|
* @param string $phpfullcodestringold PHP old string
|
||||||
|
* @param string $phpfullcodestring PHP new string
|
||||||
|
* @return int Error or not
|
||||||
|
*/
|
||||||
|
function checkPHPCode($phpfullcodestringold, $phpfullcodestring)
|
||||||
|
{
|
||||||
|
global $conf, $langs, $user;
|
||||||
|
|
||||||
|
$error = 0;
|
||||||
|
|
||||||
|
if (empty($phpfullcodestringold) && empty($phpfullcodestring)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First check forbidden commands
|
||||||
|
$forbiddenphpcommands = array();
|
||||||
|
if (empty($conf->global->WEBSITE_PHP_ALLOW_EXEC)) { // If option is not on, we disallow functions to execute commands
|
||||||
|
$forbiddenphpcommands = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI");
|
||||||
|
}
|
||||||
|
if (empty($conf->global->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 (empty($conf->global->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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$error && empty($user->rights->website->writephp)) {
|
||||||
|
if ($phpfullcodestringold != $phpfullcodestring) {
|
||||||
|
$error++;
|
||||||
|
setEventMessages($langs->trans("NotAllowedToAddDynamicContent"), null, 'errors');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $error;
|
||||||
|
}
|
||||||
|
|||||||
@ -1407,6 +1407,13 @@ if ($action == 'updatecss' && $usercanedit) {
|
|||||||
|
|
||||||
|
|
||||||
// Html header file
|
// Html header file
|
||||||
|
$phpfullcodestringold = '';
|
||||||
|
$phpfullcodestring = dolKeepOnlyPhpCode(GETPOST('WEBSITE_HTML_HEADER', 'none'));
|
||||||
|
|
||||||
|
// Security analysis
|
||||||
|
$errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
|
||||||
|
|
||||||
|
if (!$errorphpcheck) {
|
||||||
$htmlheadercontent = '';
|
$htmlheadercontent = '';
|
||||||
|
|
||||||
/* We disable php code since htmlheader is never executed as an include but only read by fgets_content.
|
/* We disable php code since htmlheader is never executed as an include but only read by fgets_content.
|
||||||
@ -1432,9 +1439,19 @@ if ($action == 'updatecss' && $usercanedit) {
|
|||||||
$error++;
|
$error++;
|
||||||
setEventMessages('Failed to write file '.$filehtmlheader, null, 'errors');
|
setEventMessages('Failed to write file '.$filehtmlheader, null, 'errors');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Css file
|
// Css file
|
||||||
|
$phpfullcodestringold = '';
|
||||||
|
$phpfullcodestring = dolKeepOnlyPhpCode(GETPOST('WEBSITE_CSS_INLINE', 'none'));
|
||||||
|
|
||||||
|
// Security analysis
|
||||||
|
$errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
|
||||||
|
|
||||||
|
if (!$errorphpcheck) {
|
||||||
$csscontent = '';
|
$csscontent = '';
|
||||||
|
|
||||||
$csscontent .= "<?php // BEGIN PHP\n";
|
$csscontent .= "<?php // BEGIN PHP\n";
|
||||||
@ -1462,9 +1479,19 @@ if ($action == 'updatecss' && $usercanedit) {
|
|||||||
$error++;
|
$error++;
|
||||||
setEventMessages('Failed to write file '.$filecss, null, 'errors');
|
setEventMessages('Failed to write file '.$filecss, null, 'errors');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Js file
|
// Js file
|
||||||
|
$phpfullcodestringold = '';
|
||||||
|
$phpfullcodestring = dolKeepOnlyPhpCode(GETPOST('WEBSITE_JS_INLINE', 'none'));
|
||||||
|
|
||||||
|
// Security analysis
|
||||||
|
$errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
|
||||||
|
|
||||||
|
if (!$errorphpcheck) {
|
||||||
$jscontent = '';
|
$jscontent = '';
|
||||||
|
|
||||||
$jscontent .= "<?php // BEGIN PHP\n";
|
$jscontent .= "<?php // BEGIN PHP\n";
|
||||||
@ -1488,9 +1515,19 @@ if ($action == 'updatecss' && $usercanedit) {
|
|||||||
$error++;
|
$error++;
|
||||||
setEventMessages('Failed to write file '.$filejs, null, 'errors');
|
setEventMessages('Failed to write file '.$filejs, null, 'errors');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Robot file
|
// Robot file
|
||||||
|
$phpfullcodestringold = '';
|
||||||
|
$phpfullcodestring = dolKeepOnlyPhpCode(GETPOST('WEBSITE_ROBOT', 'restricthtml'));
|
||||||
|
|
||||||
|
// Security analysis
|
||||||
|
$errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
|
||||||
|
|
||||||
|
if (!$errorphpcheck) {
|
||||||
$robotcontent = '';
|
$robotcontent = '';
|
||||||
|
|
||||||
/*$robotcontent.= "<?php // BEGIN PHP\n";
|
/*$robotcontent.= "<?php // BEGIN PHP\n";
|
||||||
@ -1514,9 +1551,19 @@ if ($action == 'updatecss' && $usercanedit) {
|
|||||||
$error++;
|
$error++;
|
||||||
setEventMessages('Failed to write file '.$filerobot, null, 'errors');
|
setEventMessages('Failed to write file '.$filerobot, null, 'errors');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Htaccess file
|
// Htaccess file
|
||||||
|
$phpfullcodestringold = '';
|
||||||
|
$phpfullcodestring = dolKeepOnlyPhpCode(GETPOST('WEBSITE_HTACCESS', 'restricthtml'));
|
||||||
|
|
||||||
|
// Security analysis
|
||||||
|
$errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
|
||||||
|
|
||||||
|
if (!$errorphpcheck) {
|
||||||
$htaccesscontent = '';
|
$htaccesscontent = '';
|
||||||
$htaccesscontent .= trim(GETPOST('WEBSITE_HTACCESS', 'restricthtml'))."\n";
|
$htaccesscontent .= trim(GETPOST('WEBSITE_HTACCESS', 'restricthtml'))."\n";
|
||||||
|
|
||||||
@ -1525,9 +1572,19 @@ if ($action == 'updatecss' && $usercanedit) {
|
|||||||
$error++;
|
$error++;
|
||||||
setEventMessages('Failed to write file '.$filehtaccess, null, 'errors');
|
setEventMessages('Failed to write file '.$filehtaccess, null, 'errors');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// manifest.json file
|
// Manifest.json file
|
||||||
|
$phpfullcodestringold = '';
|
||||||
|
$phpfullcodestring = dolKeepOnlyPhpCode(GETPOST('WEBSITE_MANIFEST_JSON', 'none'));
|
||||||
|
|
||||||
|
// Security analysis
|
||||||
|
$errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
|
||||||
|
|
||||||
|
if (!$errorphpcheck) {
|
||||||
$manifestjsoncontent = '';
|
$manifestjsoncontent = '';
|
||||||
|
|
||||||
$manifestjsoncontent .= "<?php // BEGIN PHP\n";
|
$manifestjsoncontent .= "<?php // BEGIN PHP\n";
|
||||||
@ -1551,9 +1608,19 @@ if ($action == 'updatecss' && $usercanedit) {
|
|||||||
$error++;
|
$error++;
|
||||||
setEventMessages('Failed to write file '.$filemanifestjson, null, 'errors');
|
setEventMessages('Failed to write file '.$filemanifestjson, null, 'errors');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// README.md file
|
// README.md file
|
||||||
|
$phpfullcodestringold = '';
|
||||||
|
$phpfullcodestring = dolKeepOnlyPhpCode(GETPOST('WEBSITE_README', 'restricthtml'));
|
||||||
|
|
||||||
|
// Security analysis
|
||||||
|
$errorphpcheck = checkPHPCode($phpfullcodestringold, $phpfullcodestring); // Contains the setEventMessages
|
||||||
|
|
||||||
|
if (!$errorphpcheck) {
|
||||||
$readmecontent = '';
|
$readmecontent = '';
|
||||||
|
|
||||||
/*$readmecontent.= "<?php // BEGIN PHP\n";
|
/*$readmecontent.= "<?php // BEGIN PHP\n";
|
||||||
@ -1577,6 +1644,9 @@ if ($action == 'updatecss' && $usercanedit) {
|
|||||||
$error++;
|
$error++;
|
||||||
setEventMessages('Failed to write file '.$filereadme, null, 'errors');
|
setEventMessages('Failed to write file '.$filereadme, null, 'errors');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Save wrapper.php
|
// Save wrapper.php
|
||||||
@ -1999,51 +2069,12 @@ if ($usercanedit && (($action == 'updatesource' || $action == 'updatecontent' ||
|
|||||||
|
|
||||||
$objectpage->content = GETPOST('PAGE_CONTENT', 'none');
|
$objectpage->content = GETPOST('PAGE_CONTENT', 'none');
|
||||||
|
|
||||||
// Security analysis
|
|
||||||
$phpfullcodestring = dolKeepOnlyPhpCode($objectpage->content);
|
$phpfullcodestring = dolKeepOnlyPhpCode($objectpage->content);
|
||||||
|
|
||||||
// First check forbidden commands
|
// Security analysis
|
||||||
$forbiddenphpcommands = array();
|
$error = checkPHPCode($phpfullcodestringold, $phpfullcodestring);
|
||||||
if (empty($conf->global->WEBSITE_PHP_ALLOW_EXEC)) { // If option is not on, we disallow functions to execute commands
|
|
||||||
$forbiddenphpcommands = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI");
|
|
||||||
}
|
|
||||||
if (empty($conf->global->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');
|
|
||||||
if ($action == 'updatesource') {
|
|
||||||
$action = 'editsource';
|
|
||||||
}
|
|
||||||
if ($action == 'updatecontent') {
|
|
||||||
$action = 'editcontent';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// This char can be used to execute RCE for example using with echo `ls`
|
|
||||||
$forbiddenphpchars = array();
|
|
||||||
if (empty($conf->global->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');
|
|
||||||
if ($action == 'updatesource') {
|
|
||||||
$action = 'editsource';
|
|
||||||
}
|
|
||||||
if ($action == 'updatecontent') {
|
|
||||||
$action = 'editcontent';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($user->rights->website->writephp)) {
|
if ($error) {
|
||||||
if ($phpfullcodestringold != $phpfullcodestring) {
|
|
||||||
$error++;
|
|
||||||
setEventMessages($langs->trans("NotAllowedToAddDynamicContent"), null, 'errors');
|
|
||||||
if ($action == 'updatesource') {
|
if ($action == 'updatesource') {
|
||||||
$action = 'editsource';
|
$action = 'editsource';
|
||||||
}
|
}
|
||||||
@ -2051,7 +2082,6 @@ if ($usercanedit && (($action == 'updatesource' || $action == 'updatecontent' ||
|
|||||||
$action = 'editcontent';
|
$action = 'editcontent';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Clean data. We remove all the head section.
|
// Clean data. We remove all the head section.
|
||||||
$objectpage->content = preg_replace('/<head>.*<\/head>/ims', '', $objectpage->content);
|
$objectpage->content = preg_replace('/<head>.*<\/head>/ims', '', $objectpage->content);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user