Protect dynamic php content with installmodules.lock

This commit is contained in:
Laurent Destailleur 2022-11-29 18:01:27 +01:00
parent 261320e551
commit c97c185368
3 changed files with 140 additions and 70 deletions

View File

@ -722,11 +722,31 @@ function checkPHPCode($phpfullcodestringold, $phpfullcodestring)
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", '$...('), null, 'errors');
}
if (!$error && empty($user->rights->website->writephp)) {
if ($phpfullcodestringold != $phpfullcodestring) {
if ($phpfullcodestringold != $phpfullcodestring) {
if (!$error && empty($user->rights->website->writephp)) {
$error++;
setEventMessages($langs->trans("NotAllowedToAddDynamicContent"), null, 'errors');
}
if (!$error) {
$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
$allowimportsite = true;
if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
$allowimportsite = false;
}
if (!$allowimportsite) {
$error++;
// Blocked by installmodules.lock
if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
// Show clean corporate message
$message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
} else {
// Show technical generic message
$message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
}
setEventMessages($message, null, 'errors');
}
}
}
return $error;

View File

@ -1932,7 +1932,7 @@ BackupDumpWizard=Wizard to build the database dump file
BackupZipWizard=Wizard to build the archive of documents directory
SomethingMakeInstallFromWebNotPossible=Installation of external module is not possible from the web interface for the following reason:
SomethingMakeInstallFromWebNotPossible2=For this reason, process to upgrade described here is a manual process only a privileged user may perform.
InstallModuleFromWebHasBeenDisabledContactUs=Install or development of external modules from the application is currently locked for security purpose. Please contact us if you need to enable this feature.
InstallModuleFromWebHasBeenDisabledContactUs=Install or development of external modules or dynamic websites, from the application, is currently locked for security purpose. Please contact us if you need to enable this feature.
InstallModuleFromWebHasBeenDisabledByFile=Install of external module from application has been disabled by your administrator. You must ask him to remove the file <strong>%s</strong> to allow this feature.
ConfFileMustContainCustom=Installing or building an external module from application need to save the module files into directory <strong>%s</strong>. To have this directory processed by Dolibarr, you must setup your <strong>conf/conf.php</strong> to add the 2 directive lines:<br><strong>$dolibarr_main_url_root_alt='/custom';</strong><br><strong>$dolibarr_main_document_root_alt='%s/custom';</strong>
HighlightLinesOnMouseHover=Highlight table lines when mouse move passes over

View File

@ -572,7 +572,23 @@ if ($massaction == 'delcategory' && GETPOST('confirmmassaction', 'alpha') && $us
if ($massaction == 'replace' && GETPOST('confirmmassaction', 'alpha') && $usercanedit) {
$replacestring = GETPOST('replacestring', 'none');
if (empty($user->rights->website->writephp)) {
$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
$allowimportsite = true;
if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
$allowimportsite = false;
}
if (!$allowimportsite) {
// Blocked by installmodules.lock
if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
// Show clean corporate message
$message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
} else {
// Show technical generic message
$message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
}
setEventMessages($message, null, 'errors');
} elseif (empty($user->rights->website->writephp)) {
setEventMessages("NotAllowedToAddDynamicContent", null, 'errors');
} elseif (!$replacestring) {
setEventMessages("ErrorReplaceStringEmpty", null, 'errors');
@ -2377,76 +2393,93 @@ if ($action == 'regeneratesite' && $usercanedit) {
// Import site
if ($action == 'importsiteconfirm' && $usercanedit) {
if (empty($_FILES) && !GETPOSTISSET('templateuserfile')) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
$action = 'importsite';
} else {
if (!empty($_FILES) || GETPOSTISSET('templateuserfile')) {
// Check symlink to medias and restore it if ko. Recreate also dir of website if not found.
$pathtomedias = DOL_DATA_ROOT.'/medias';
$pathtomediasinwebsite = $pathofwebsite.'/medias';
if (!is_link(dol_osencode($pathtomediasinwebsite))) {
dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure dir for website exists
$result = symlink($pathtomedias, $pathtomediasinwebsite);
if (!$result) {
setEventMessages($langs->trans("ErrorFieldToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
$action = 'importsite';
}
}
$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
$allowimportsite = true;
if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
$allowimportsite = false;
}
$fileofzip = '';
if (GETPOSTISSET('templateuserfile')) {
$fileofzip = DOL_DATA_ROOT.'/doctemplates/websites/'.GETPOST('templateuserfile', 'alpha');
} elseif (!empty($_FILES)) {
if (is_array($_FILES['userfile']['tmp_name'])) {
$userfiles = $_FILES['userfile']['tmp_name'];
} else {
$userfiles = array($_FILES['userfile']['tmp_name']);
if ($allowimportsite) {
if (empty($_FILES) && !GETPOSTISSET('templateuserfile')) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
$action = 'importsite';
} else {
if (!empty($_FILES) || GETPOSTISSET('templateuserfile')) {
// Check symlink to medias and restore it if ko. Recreate also dir of website if not found.
$pathtomedias = DOL_DATA_ROOT.'/medias';
$pathtomediasinwebsite = $pathofwebsite.'/medias';
if (!is_link(dol_osencode($pathtomediasinwebsite))) {
dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
dol_mkdir(dirname($pathtomediasinwebsite)); // To be sure dir for website exists
$result = symlink($pathtomedias, $pathtomediasinwebsite);
if (!$result) {
setEventMessages($langs->trans("ErrorFieldToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
$action = 'importsite';
}
}
foreach ($userfiles as $key => $userfile) {
if (empty($_FILES['userfile']['tmp_name'][$key])) {
$error++;
if ($_FILES['userfile']['error'][$key] == 1 || $_FILES['userfile']['error'][$key] == 2) {
setEventMessages($langs->trans('ErrorFileSizeTooLarge'), null, 'errors');
$action = 'importsite';
} else {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
$action = 'importsite';
$fileofzip = '';
if (GETPOSTISSET('templateuserfile')) {
$fileofzip = DOL_DATA_ROOT.'/doctemplates/websites/'.GETPOST('templateuserfile', 'alpha');
} elseif (!empty($_FILES)) {
if (is_array($_FILES['userfile']['tmp_name'])) {
$userfiles = $_FILES['userfile']['tmp_name'];
} else {
$userfiles = array($_FILES['userfile']['tmp_name']);
}
foreach ($userfiles as $key => $userfile) {
if (empty($_FILES['userfile']['tmp_name'][$key])) {
$error++;
if ($_FILES['userfile']['error'][$key] == 1 || $_FILES['userfile']['error'][$key] == 2) {
setEventMessages($langs->trans('ErrorFileSizeTooLarge'), null, 'errors');
$action = 'importsite';
} else {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
$action = 'importsite';
}
}
}
if (!$error) {
$upload_dir = $conf->website->dir_temp;
$result = dol_add_file_process($upload_dir, 1, -1, 'userfile', '');
}
// Get name of file (take last one if several name provided)
$fileofzip = $upload_dir.'/unknown';
foreach ($_FILES as $key => $ifile) {
foreach ($ifile['name'] as $key2 => $ifile2) {
$fileofzip = $upload_dir.'/'.$ifile2;
}
}
}
if (!$error) {
$upload_dir = $conf->website->dir_temp;
$result = dol_add_file_process($upload_dir, 1, -1, 'userfile', '');
}
$result = $object->importWebSite($fileofzip);
// Get name of file (take last one if several name provided)
$fileofzip = $upload_dir.'/unknown';
foreach ($_FILES as $key => $ifile) {
foreach ($ifile['name'] as $key2 => $ifile2) {
$fileofzip = $upload_dir.'/'.$ifile2;
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
$action = 'importsite';
} else {
// Force mode dynamic on
dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 1, 'chaine', 0, '', $conf->entity);
header("Location: ".$_SERVER["PHP_SELF"].'?website='.$object->ref);
exit();
}
}
}
if (!$error) {
$result = $object->importWebSite($fileofzip);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
$action = 'importsite';
} else {
// Force mode dynamic on
dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 1, 'chaine', 0, '', $conf->entity);
header("Location: ".$_SERVER["PHP_SELF"].'?website='.$object->ref);
exit();
}
}
}
} else {
if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
// Show clean corporate message
$message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
} else {
// Show technical generic message
$message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
}
setEventMessages($message, null, 'errors');
}
}
@ -3847,16 +3880,33 @@ if ($action == 'importsite') {
print '<span class="opacitymedium">'.$langs->trans("ZipOfWebsitePackageToImport").'</span><br><br>';
$maxfilesizearray = getMaxFileSizeArray();
$maxmin = $maxfilesizearray['maxmin'];
if ($maxmin > 0) {
print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
}
print '<input class="flat minwidth400" type="file" name="userfile[]" accept=".zip">';
print '<input type="submit" class="button small" name="buttonsubmitimportfile" value="'.dol_escape_htmltag($langs->trans("Upload")).'">';
print '<input type="submit" class="button button-cancel small" name="preview" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '<br><br><br>';
$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
$allowimportsite = true;
if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
$allowimportsite = false;
}
if ($allowimportsite) {
$maxfilesizearray = getMaxFileSizeArray();
$maxmin = $maxfilesizearray['maxmin'];
if ($maxmin > 0) {
print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
}
print '<input class="flat minwidth400" type="file" name="userfile[]" accept=".zip">';
print '<input type="submit" class="button small" name="buttonsubmitimportfile" value="'.dol_escape_htmltag($langs->trans("Upload")).'">';
print '<input type="submit" class="button button-cancel small" name="preview" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '<br><br><br>';
} else {
if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
// Show clean corporate message
$message = $langs->trans('InstallModuleFromWebHasBeenDisabledContactUs');
} else {
// Show technical generic message
$message = $langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock');
}
print info_admin($message).'<br><br>';
}
print '<span class="opacitymedium">'.$langs->trans("ZipOfWebsitePackageToLoad").'</span><br><br>';