CVE-2015-5959 (PHP, published 2017-09-06T21:29Z)
Description: value: Froxlor before 0.9.33.2 with the default configuration/setup might allow remote attackers to obtain the database password by reading /logs/sql-error.log.
Severity: MEDIUM (CVSS v3 base score: 9.8)
Weakness: CWE-200 \u2014 Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
Repository: https://github.com/Froxlor/Froxlor
Files changed:
lib/classes/database/class.Database.php
Commit message: replace passwords even before logging, not just for display

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


Vulnerable code:
		@fwrite($sqllog, date('d.m.Y H:i', time())." --- ".str_replace("\n", " ", $error->getMessage())."\n");
		@fwrite($sqllog, date('d.m.Y H:i', time())." --- DEBUG: \n".$error->getTraceAsString()."\n");
		@fwrite($errlog, "|MSG ".$error->getMessage()."\n");
		@fwrite($errlog, "|TRACE\n".$error->getTraceAsString()."\n");
			// include userdata.inc.php
			require FROXLOR_INSTALL_DIR."/lib/userdata.inc.php";

			// le format
			if (isset($sql['root_user'])
				&& isset($sql['root_password'])
				&& (!isset($sql_root) || !is_array($sql_root))
			) {
				$sql_root = array(0 => array('caption' => 'Default', 'host' => $sql['host'], 'socket' => (isset($sql['socket']) ? $sql['socket'] : null), 'user' => $sql['root_user'], 'password' => $sql['root_password']));
			}

			// hide username/password in messages
			$error_message = $error->getMessage();
			$error_trace = $error->getTraceAsString();
			// error-message
			$error_message = str_replace($sql['password'], 'DB_UNPRIV_PWD', $error_message);
			$error_message = str_replace($sql_root[0]['password'], 'DB_ROOT_PWD', $error_message);
			// error-trace
			$error_trace = str_replace($sql['password'], 'DB_UNPRIV_PWD', $error_trace);
			$error_trace = str_replace($sql_root[0]['password'], 'DB_ROOT_PWD', $error_trace);

			if ($error->getCode() == 2003) {
			    $error_message = "Unable to connect to database. Either the mysql-server is not running or your user/password is wrong.";
			    $error_trace = "";
			}


Fixed code:
		// include userdata.inc.php
		require FROXLOR_INSTALL_DIR."/lib/userdata.inc.php";

		// le format
		if (isset($sql['root_user'])
		    && isset($sql['root_password'])
		    && (!isset($sql_root) || !is_array($sql_root))
		) {
		    $sql_root = array(0 => array('caption' => 'Default', 'host' => $sql['host'], 'socket' => (isset($sql['socket']) ? $sql['socket'] : null), 'user' => $sql['root_user'], 'password' => $sql['root_password']));
		}

		// hide username/password in messages
		$error_message = $error->getMessage();
		$error_trace = $error->getTraceAsString();
		// error-message
		$error_message = str_replace($sql['password'], 'DB_UNPRIV_PWD', $error_message);
		$error_message = str_replace($sql_root[0]['password'], 'DB_ROOT_PWD', $error_message);
		// error-trace
		$error_trace = str_replace($sql['password'], 'DB_UNPRIV_PWD', $error_trace);
		$error_trace = str_replace($sql_root[0]['password'], 'DB_ROOT_PWD', $error_trace);

		if ($error->getCode() == 2003) {
		    $error_message = "Unable to connect to database. Either the mysql-server is not running or your user/password is wrong.";
		    $error_trace = "";
		}

		@fwrite($sqllog, date('d.m.Y H:i', time())." --- ".str_replace("\n", " ", $error_message)."\n");
		@fwrite($sqllog, date('d.m.Y H:i', time())." --- DEBUG: \n".$error_trace."\n");
		@fwrite($errlog, "|MSG ".$error_message."\n");
		@fwrite($errlog, "|TRACE\n".$error_trace."\n");