CVE-2020-10236: Improper Input Validation (CWE-20)
value: An issue was discovered in Froxlor before 0.10.14. It created files with static names in /tmp during installation if the installation directory was not writable. This allowed local attackers to cause DoS or disclose information out of the config files, because of _createUserdataConf in install/lib/class.FroxlorInstall.php.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
CVSS v3 base score: 6.1
Published: 2020-03-09T16:15Z
Repository: https://github.com/Froxlor/Froxlor
Language: PHP
Files changed: install/lib/class.FroxlorInstall.php, install/lng/english.lng.php, install/lng/french.lng.php, install/lng/german.lng.php
Commit date: 2020-03-04 19:34:18 +0100
Commit message: use unpredictable tmpfile-name in installation if lib/userdata.inc.php cannot be written due to permission

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

Diff: diff --git a/install/lib/class.FroxlorInstall.php b/install/lib/class.FroxlorInstall.php
index ddc3166ab..11a16bfb8 100644
--- a/install/lib/class.FroxlorInstall.php
+++ b/install/lib/class.FroxlorInstall.php
@@ -336,19 +336,24 @@ class FroxlorInstall
 		if ($fp = @fopen($userdata_file, 'w')) {
 			$result = @fputs($fp, $userdata, strlen($userdata));
 			@fclose($fp);
 			$content .= $this->_status_message('green', 'OK');
 			chmod($userdata_file, 0440);
-		} elseif ($fp = @fopen('/tmp/userdata.inc.php', 'w')) {
-			$result = @fputs($fp, $userdata, strlen($userdata));
-			@fclose($fp);
-			$content .= $this->_status_message('orange', $this->_lng['install']['creating_configfile_temp']);
-			chmod('/tmp/userdata.inc.php', 0440);
 		} else {
-			$content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']);
-			$escpduserdata = nl2br(htmlspecialchars($userdata));
-			eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";");
+			// try creating it in a temporary file
+			$temp_file = tempnam(sys_get_temp_dir(), 'fx');
+			if (touch($temp_file)) {
+				chmod($temp_file, 0400);
+				$fp = @fopen($temp_file, 'w');
+				$result = @fputs($fp, $userdata, strlen($userdata));
+				@fclose($fp);
+				$content .= $this->_status_message('orange', sprintf($this->_lng['install']['creating_configfile_temp'], $temp_file));
+			} else {
+				$content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']);
+				$escpduserdata = nl2br(htmlspecialchars($userdata));
+				eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";");
+			}
 		}
 
 		return $content;
 	}
 
diff --git a/install/lng/english.lng.php b/install/lng/english.lng.php
index b7dd5ef86..e5e6b9cb1 100644
--- a/install/lng/english.lng.php
+++ b/install/lng/english.lng.php
@@ -84,11 +84,11 @@ $lng['install']['testing_new_db'] = 'Testing if database and user have been crea
 $lng['install']['importing_data'] = 'Importing data...';
 $lng['install']['changing_data'] = 'Adjusting settings...';
 $lng['install']['creating_entries'] = 'Inserting new values...';
 $lng['install']['adding_admin_user'] = 'Creating admin-account...';
 $lng['install']['creating_configfile'] = 'Creating configfile...';
-$lng['install']['creating_configfile_temp'] = 'File was saved in /tmp/userdata.inc.php, please move to ' . dirname(dirname(__DIR__)) . '/lib/.';
+$lng['install']['creating_configfile_temp'] = 'File was saved in %s, please move to ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php';
 $lng['install']['creating_configfile_failed'] = 'Could not create ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, please create it manually with the following content:';
 $lng['install']['froxlor_succ_installed'] = 'Froxlor was installed successfully.';
 
 $lng['click_here_to_refresh'] = 'Click here to check again';
 $lng['click_here_to_goback'] = 'Click here to go back';
diff --git a/install/lng/french.lng.php b/install/lng/french.lng.php
index fdb733ceb..42ab1d7b7 100644
--- a/install/lng/french.lng.php
+++ b/install/lng/french.lng.php
@@ -74,11 +74,11 @@ $lng['install']['testing_new_db'] = 'Teste si la base de données et l\'utilisat
 $lng['install']['importing_data'] = 'Import des données...';
 $lng['install']['changing_data'] = 'Ajustement des paramètres...';
 $lng['install']['creating_entries'] = 'Insertion des nouvelles valeurs...';
 $lng['install']['adding_admin_user'] = 'Création du compte administrateur...';
 $lng['install']['creating_configfile'] = 'Création du fichier de configuration...';
-$lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans /tmp/userdata.inc.php, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/.';
+$lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans %s, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php';
 $lng['install']['creating_configfile_failed'] = 'Impossible de créer ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, merci de le créer manuellement avec le contenu suivant:';
 $lng['install']['froxlor_succ_installed'] = 'Froxlor a été installé avec succès.';
 
 $lng['click_here_to_refresh'] = 'Cliquez ici pour vérifier à nouveau';
 $lng['click_here_to_goback'] = 'Cliquez ici pour revenir';
diff --git a/install/lng/german.lng.php b/install/lng/german.lng.php
index 1f95decca..64b462b42 100644
--- a/install/lng/german.lng.php
+++ b/install/lng/german.lng.php
@@ -84,11 +84,11 @@ $lng['install']['testing_new_db'] = 'Teste, ob Datenbank und Benutzer korrekt an
 $lng['install']['importing_data'] = 'Importiere Daten...';
 $lng['install']['changing_data'] = 'Einstellungen anpassen...';
 $lng['install']['creating_entries'] = 'Trage neue Werte ein...';
 $lng['install']['adding_admin_user'] = 'Erstelle Admin-Benutzer...';
 $lng['install']['creating_configfile'] = 'Erstelle Konfigurationsdatei...';
-$lng['install']['creating_configfile_temp'] = 'Datei wurde in /tmp/userdata.inc.php gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/ verschieben.';
+$lng['install']['creating_configfile_temp'] = 'Datei wurde in %s gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php verschieben.';
 $lng['install']['creating_configfile_failed'] = 'Konnte ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php nicht erstellen, bitte manuell mit folgendem Inhalt anlegen:';
 $lng['install']['froxlor_succ_installed'] = 'Froxlor wurde erfolgreich installiert.';
 
 $lng['click_here_to_refresh'] = 'Hier klicken, um erneut zu prüfen';
 $lng['click_here_to_goback'] = 'Einen Schritt zurück';

Vulnerable code: 		} elseif ($fp = @fopen('/tmp/userdata.inc.php', 'w')) {
			$result = @fputs($fp, $userdata, strlen($userdata));
			@fclose($fp);
			$content .= $this->_status_message('orange', $this->_lng['install']['creating_configfile_temp']);
			chmod('/tmp/userdata.inc.php', 0440);
			$content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']);
			$escpduserdata = nl2br(htmlspecialchars($userdata));
			eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";");
$lng['install']['creating_configfile_temp'] = 'File was saved in /tmp/userdata.inc.php, please move to ' . dirname(dirname(__DIR__)) . '/lib/.';
$lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans /tmp/userdata.inc.php, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/.';
$lng['install']['creating_configfile_temp'] = 'Datei wurde in /tmp/userdata.inc.php gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/ verschieben.';
Fixed code: 			// try creating it in a temporary file
			$temp_file = tempnam(sys_get_temp_dir(), 'fx');
			if (touch($temp_file)) {
				chmod($temp_file, 0400);
				$fp = @fopen($temp_file, 'w');
				$result = @fputs($fp, $userdata, strlen($userdata));
				@fclose($fp);
				$content .= $this->_status_message('orange', sprintf($this->_lng['install']['creating_configfile_temp'], $temp_file));
			} else {
				$content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']);
				$escpduserdata = nl2br(htmlspecialchars($userdata));
				eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";");
			}
$lng['install']['creating_configfile_temp'] = 'File was saved in %s, please move to ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php';
$lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans %s, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php';
$lng['install']['creating_configfile_temp'] = 'Datei wurde in %s gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php verschieben.';