CVE-2023-0315: Improper Neutralization of Special Elements used in a Command ('Command Injection') (CWE-77)
value: Command Injection in GitHub repository froxlor/froxlor prior to 2.0.8.
CWE description: The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component.
CVSS v3 base score: 8.8
Published: 2023-01-16T01:15Z
Repository: https://github.com/froxlor/froxlor
Language: PHP
Files changed: install/froxlor.sql.php, install/updates/froxlor/update_2.x.inc.php, lib/Froxlor/Froxlor.php, lib/Froxlor/FroxlorLogger.php, lib/configfiles/bionic.xml, lng/de.lng.php, lng/en.lng.php
Commit date: 2023-01-14 13:09:42 +0100
Commit message: set file-log (if enabled) to be in froxlor/logs/ folder; fix ssl param directive for dovecot in Ubuntu Bionic; set version to 2.0.8

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>

Diff: diff --git a/install/froxlor.sql.php b/install/froxlor.sql.php
index 90326c372..c82e6ad64 100644
--- a/install/froxlor.sql.php
+++ b/install/froxlor.sql.php
@@ -694,11 +694,11 @@ opcache.validate_timestamps'),
 	('system', 'froxlorusergroup_gid', ''),
 	('system', 'acmeshpath', '/root/.acme.sh/acme.sh'),
 	('system', 'distribution', ''),
 	('system', 'update_channel', 'stable'),
 	('system', 'updatecheck_data', ''),
-	('system', 'update_notify_last', '2.0.7'),
+	('system', 'update_notify_last', '2.0.8'),
 	('system', 'traffictool', 'goaccess'),
 	('api', 'enabled', '0'),
 	('2fa', 'enabled', '1'),
 	('panel', 'decimal_places', '4'),
 	('panel', 'adminmail', 'admin@SERVERNAME'),
@@ -738,11 +738,11 @@ opcache.validate_timestamps'),
 	('panel', 'logo_image_header', ''),
 	('panel', 'logo_image_login', ''),
 	('panel', 'logo_overridetheme', '0'),
 	('panel', 'logo_overridecustom', '0'),
 	('panel', 'settings_mode', '0'),
-	('panel', 'version', '2.0.7'),
+	('panel', 'version', '2.0.8'),
 	('panel', 'db_version', '202301120');
 
 
 DROP TABLE IF EXISTS `panel_tasks`;
 CREATE TABLE `panel_tasks` (
diff --git a/install/updates/froxlor/update_2.x.inc.php b/install/updates/froxlor/update_2.x.inc.php
index 73b3b5d55..a2e8baf0a 100644
--- a/install/updates/froxlor/update_2.x.inc.php
+++ b/install/updates/froxlor/update_2.x.inc.php
@@ -328,5 +328,19 @@ if (Froxlor::isDatabaseVersion('202212060')) {
 		Update::lastStepStatus(0);
 	}
 
 	Froxlor::updateToDbVersion('202301120');
 }
+
+if (Froxlor::isFroxlorVersion('2.0.7')) {
+	Update::showUpdateStep("Updating from 2.0.7 to 2.0.8", false);
+
+	// adjust file-logging to be set to froxlor/logs/
+	$logtypes = explode(',', Settings::Get('logger.logtypes'));
+	if (in_array('file', $logtypes)) {
+		Update::showUpdateStep("Adjusting froxlor logfile for system-logging to be stored in logs/froxlor.log");
+		Settings::Set('logger.logfile', 'froxlor.log');
+		Update::lastStepStatus(0);
+	}
+
+	Froxlor::updateToVersion('2.0.8');
+}
diff --git a/lib/Froxlor/Froxlor.php b/lib/Froxlor/Froxlor.php
index 05485f6dd..98ce9e786 100644
--- a/lib/Froxlor/Froxlor.php
+++ b/lib/Froxlor/Froxlor.php
@@ -29,11 +29,11 @@ use Froxlor\Database\Database;
 
 final class Froxlor
 {
 
 	// Main version variable
-	const VERSION = '2.0.7';
+	const VERSION = '2.0.8';
 
 	// Database version (YYYYMMDDC where C is a daily counter)
 	const DBVERSION = '202301120';
 
 	// Distribution branding-tag (used for Debian etc.)
diff --git a/lib/Froxlor/FroxlorLogger.php b/lib/Froxlor/FroxlorLogger.php
index dcc2eb2f6..4bbd5e099 100644
--- a/lib/Froxlor/FroxlorLogger.php
+++ b/lib/Froxlor/FroxlorLogger.php
@@ -98,15 +98,21 @@ class FroxlorLogger
 				switch ($logger) {
 					case 'syslog':
 						self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG));
 						break;
 					case 'file':
-						$logger_logfile = Settings::Get('logger.logfile');
+						$logger_logfile = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/logs/' . Settings::Get('logger.logfile'));
 						// is_writable needs an existing file to check if it's actually writable
 						@touch($logger_logfile);
 						if (empty($logger_logfile) || !is_writable($logger_logfile)) {
-							Settings::Set('logger.logfile', '/tmp/froxlor.log');
+							Settings::Set('logger.logfile', 'froxlor.log');
+							$logger_logfile = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/logs/froxlor.log');
+							@touch($logger_logfile);
+							if (empty($logger_logfile) || !is_writable($logger_logfile)) {
+								// not writable in our own directory? Skip
+								break;
+							}
 						}
 						self::$ml->pushHandler(new StreamHandler($logger_logfile, Logger::DEBUG));
 						break;
 					case 'mysql':
 						self::$ml->pushHandler(new MysqlHandler(Logger::DEBUG));
diff --git a/lib/configfiles/bionic.xml b/lib/configfiles/bionic.xml
index 6fd9a68b3..f91b0d553 100644
--- a/lib/configfiles/bionic.xml
+++ b/lib/configfiles/bionic.xml
@@ -3456,15 +3456,11 @@ ssl_key = <<SSL_KEY_FILE>
 # Which field from certificate to use for username. commonName and
 # x500UniqueIdentifier are the usual choices. You'll also need to set
 # auth_ssl_username_from_cert=yes.
 #ssl_cert_username_field = commonName
 
-# SSL DH parameters
-# Generate new params with `openssl dhparam -out /etc/dovecot/dh.pem 4096`
-# Or migrate from old ssl-parameters.dat file with the command dovecot
-# gives on startup when ssl_dh is unset.
-ssl_dh = </usr/share/dovecot/dh.pem
+ssl_dh_parameters_length = 2048
 
 # SSL protocols to use
 #ssl_protocols = !SSLv3
 
 # SSL ciphers to use
diff --git a/lng/de.lng.php b/lng/de.lng.php
index b6b841512..3c3897012 100644
--- a/lng/de.lng.php
+++ b/lng/de.lng.php
@@ -1492,11 +1492,14 @@ Vielen Dank, Ihr Administrator',
 			'severity' => 'Logging Level',
 			'types' => [
 				'title' => 'Log-Art(en)',
 				'description' => 'Wählen Sie hier die gewünschten Logtypen. Für Mehrfachauswahl, halten Sie während der Auswahl STRG gedrückt<br />Mögliche Logtypen sind: syslog, file, mysql',
 			],
-			'logfile' => 'Log-Datei Pfad inklusive Dateinamen',
+			'logfile' => [
+				'title' => 'Dateiname der Logdatei',
+				'description' => 'Wird nur verwendet, wenn die Log-Art "file" ausgewählt ist. Diese Datei wird unter froxlor/logs/ geschrieben. Dieser Ordner ist vor Webzugriff geschützt.',
+			],
 			'logcron' => 'Logge Cronjobs',
 			'logcronoption' => [
 				'never' => 'Nie',
 				'once' => 'Einmalig',
 				'always' => 'Immer',
diff --git a/lng/en.lng.php b/lng/en.lng.php
index 14d275670..d7f7eca7e 100644
--- a/lng/en.lng.php
+++ b/lng/en.lng.php
@@ -1611,11 +1611,14 @@ Yours sincerely, your administrator',
 			'severity' => 'Logging level',
 			'types' => [
 				'title' => 'Log-type(s)',
 				'description' => 'Specify logtypes. To select multiple types, hold down CTRL while selecting.<br />Available logtypes are: syslog, file, mysql',
 			],
-			'logfile' => 'Logfile path including filename',
+			'logfile' => [
+				'title' => 'Filename for log',
+				'description' => 'Only used if log-type includes "file". This file will be created in froxlor/logs/. This folder is protected against public access.',
+			],
 			'logcron' => 'Log cronjobs',
 			'logcronoption' => [
 				'never' => 'Never',
 				'once' => 'Once',
 				'always' => 'Always',

Vulnerable code: 	('system', 'update_notify_last', '2.0.7'),
	('panel', 'version', '2.0.7'),
	const VERSION = '2.0.7';
						$logger_logfile = Settings::Get('logger.logfile');
							Settings::Set('logger.logfile', '/tmp/froxlor.log');
# SSL DH parameters
# Generate new params with `openssl dhparam -out /etc/dovecot/dh.pem 4096`
# Or migrate from old ssl-parameters.dat file with the command dovecot
# gives on startup when ssl_dh is unset.
ssl_dh = </usr/share/dovecot/dh.pem
			'logfile' => 'Log-Datei Pfad inklusive Dateinamen',
			'logfile' => 'Logfile path including filename',
Fixed code: 	('system', 'update_notify_last', '2.0.8'),
	('panel', 'version', '2.0.8'),

if (Froxlor::isFroxlorVersion('2.0.7')) {
	Update::showUpdateStep("Updating from 2.0.7 to 2.0.8", false);

	// adjust file-logging to be set to froxlor/logs/
	$logtypes = explode(',', Settings::Get('logger.logtypes'));
	if (in_array('file', $logtypes)) {
		Update::showUpdateStep("Adjusting froxlor logfile for system-logging to be stored in logs/froxlor.log");
		Settings::Set('logger.logfile', 'froxlor.log');
		Update::lastStepStatus(0);
	}

	Froxlor::updateToVersion('2.0.8');
}
	const VERSION = '2.0.8';
						$logger_logfile = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/logs/' . Settings::Get('logger.logfile'));
							Settings::Set('logger.logfile', 'froxlor.log');
							$logger_logfile = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/logs/froxlor.log');
							@touch($logger_logfile);
							if (empty($logger_logfile) || !is_writable($logger_logfile)) {
								// not writable in our own directory? Skip
								break;
							}
ssl_dh_parameters_length = 2048
			'logfile' => [
				'title' => 'Dateiname der Logdatei',
				'description' => 'Wird nur verwendet, wenn die Log-Art "file" ausgewählt ist. Diese Datei wird unter froxlor/logs/ geschrieben. Dieser Ordner ist vor Webzugriff geschützt.',
			],
			'logfile' => [
				'title' => 'Filename for log',
				'description' => 'Only used if log-type includes "file". This file will be created in froxlor/logs/. This folder is protected against public access.',
			],