CVE-2014-8335: Credentials Management Errors (CWE-255)
value: (1) wp-dbmanager.php and (2) database-manage.php in the WP-DBManager (aka Database Manager) plugin before 2.7.2 for WordPress place credentials on the mysqldump command line, which allows local users to obtain sensitive information by listing the process.
CWE description: Weaknesses in this category are related to the management of credentials.
CVSS v3 base score: 7.8
Published: 2018-01-05T16:29Z
Repository: https://github.com/lesterchan/wp-dbmanager
Language: PHP
Files changed: README.md, database-backup.php, database-manage.php, database-run.php, wp-dbmanager.php
Commit date: 2014-10-16 12:08:01 +0800
Commit message: Uses escapeshellcmd() and do not allow LOAD_FILE inside queries

Diff: diff --git a/README.md b/README.md
index 0e7f4fc..86469f3 100644
--- a/README.md
+++ b/README.md
@@ -32,12 +32,14 @@ Allows you to optimize database, repair database, backup database, restore datab
 * If this is a concern to you, I recommend another database backup plugin called [WP-DB-Backup](https://wordpress.org/plugins/wp-db-backup/)
 * To know about the difference between WP-DBManager and WP-DB-backup, checkout __What is the difference between WP-DBManager and WP-DB-Backup?__ in the [FAQ section](https://wordpress.org/plugins/wp-dbmanager/faq/).
 
 ## Changelog
 ### Version 2.72
-* FIXED: Use dbmanager_is_valid_path() to check for mysql and mysqldump path. Fixes arbitrary command injection using backup path. Props Larry W. Cashdollari.
-* FIXED: Use realpath() to check for backup path. Fixes arbitrary command injection using backup path. Props Larry W. Cashdollari.
+* FIXED: Uses escapeshellcmd() to escape shell commands
+* FIXED: Do not allow LOAD_FILE to be run
+* FIXED: Uses dbmanager_is_valid_path() to check for mysql and mysqldump path. Fixes arbitrary command injection using backup path. Props Larry W. Cashdollari.
+* FIXED: Uses realpath() to check for backup path. Fixes arbitrary command injection using backup path. Props Larry W. Cashdollari.
 
 ### Version 2.71
 * NEW: Bump to 4.0
 
 ### Version 2.70
diff --git a/database-backup.php b/database-backup.php
index 115cf6a..23deb8c 100644
--- a/database-backup.php
+++ b/database-backup.php
@@ -40,15 +40,15 @@ if(!empty($_POST['do'])) {
 			}
 			$gzip = intval($_POST['gzip']);
 			if($gzip == 1) {
 				$backup['filename'] = $backup['date'].'_-_'.DB_NAME.'.sql.gz';
 				$backup['filepath'] = $backup['path'].'/'.$backup['filename'];
-				$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' --add-drop-table --skip-lock-tables '.DB_NAME.' | gzip > '.$brace.$backup['filepath'].$brace;
+				$backup['command'] = escapeshellcmd( $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' --add-drop-table --skip-lock-tables '.DB_NAME ).' | gzip > '.escapeshellcmd( $brace.$backup['filepath'].$brace );
 			} else {
 				$backup['filename'] = $backup['date'].'_-_'.DB_NAME.'.sql';
 				$backup['filepath'] = $backup['path'].'/'.$backup['filename'];
-				$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' --add-drop-table --skip-lock-tables '.DB_NAME.' > '.$brace.$backup['filepath'].$brace;
+				$backup['command'] = escapeshellcmd( $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' --add-drop-table --skip-lock-tables '.DB_NAME ).' > '.escapeshellcmd( $brace.$backup['filepath'].$brace );
 			}
 			$error = execute_backup($backup['command']);
 			if(!is_writable($backup['path'])) {
 				$text = '<p style="color: red;">'.sprintf(__('Database Failed To Backup On \'%s\'. Backup Folder Not Writable.', 'wp-dbmanager'), $current_date).'</p>';
 			} elseif(filesize($backup['filepath']) == 0) {
diff --git a/database-manage.php b/database-manage.php
index 14d08e7..a31dca2 100644
--- a/database-manage.php
+++ b/database-manage.php
@@ -42,13 +42,13 @@ if( !empty( $_POST['do'] ) ) {
 					} else {
 						$backup['sock'] = ' --socket="'.$db_host[1].'"';
 					}
 				}
 				if(stristr($database_file, '.gz')) {
-					$backup['command'] = 'gunzip < '.$brace.$backup['path'].'/'.$database_file.$brace.' | '.$brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME;
+					$backup['command'] = 'gunzip < '.escapeshellcmd( $brace.$backup['path'].'/'.$database_file.$brace ).' | '.escapeshellcmd( $brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME );
 				} else {
-					$backup['command'] = $brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME.' < '.$brace.$backup['path'].'/'.$database_file.$brace;
+					$backup['command'] = escapeshellcmd( $brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME ).' < '.escapeshellcmd( $brace.$backup['path'].'/'.$database_file.$brace );
 				}
 				if( realpath( $backup['path'] ) === false ) {
 					$text = '<p style="color: red;">' . sprintf(__('%s is not a valid backup path', 'wp-dbmanager'), stripslashes( $backup['path'] ) ) . '</p>';
 				} else if( dbmanager_is_valid_path( $backup['mysqlpath'] ) === 0 ) {
 					$text = '<p style="color: red;">' . sprintf(__('%s is not a valid mysql path', 'wp-dbmanager'), stripslashes( $backup['mysqlpath'] ) ) . '</p>';
diff --git a/database-run.php b/database-run.php
index 11a0557..7802532 100644
--- a/database-run.php
+++ b/database-run.php
@@ -35,23 +35,26 @@ if(!empty($_POST['do'])) {
 					if(!empty($sql_query2)) {
 						$sql_queries[] = $sql_query2;
 					}
 				}
 				if($sql_queries) {
-					foreach($sql_queries as $sql_query) {
-						if (preg_match("/^\\s*(insert|update|replace|delete|create|alter) /i",$sql_query)) {
-							$run_query = $wpdb->query($sql_query);
-							if(!$run_query) {
+					foreach( $sql_queries as $sql_query ) {
+						if ( preg_match( "/LOAD_FILE/i", $sql_query ) ) {
+							$text .= "<p style=\"color: red;\">$sql_query</p>";
+							$totalquerycount++;
+						} elseif( preg_match( "/^\\s*(select|drop|show|grant) /i", $sql_query ) ) {
+							$text .= "<p style=\"color: red;\">$sql_query</p>";
+							$totalquerycount++;
+						} else if ( preg_match( "/^\\s*(insert|update|replace|delete|create|alter) /i", $sql_query ) ) {
+							$run_query = $wpdb->query( $sql_query );
+							if( ! $run_query ) {
 								$text .= "<p style=\"color: red;\">$sql_query</p>";
 							} else {
 								$successquery++;
 								$text .= "<p style=\"color: green;\">$sql_query</p>";
 							}
 							$totalquerycount++;
-						} elseif (preg_match("/^\\s*(select|drop|show|grant) /i",$sql_query)) {
-							$text .= "<p style=\"color: red;\">$sql_query</p>";
-							$totalquerycount++;
 						}
 					}
 					$text .= '<p style="color: blue;">'.number_format_i18n($successquery).'/'.number_format_i18n($totalquerycount).' '.__('Query(s) Executed Successfully', 'wp-dbmanager').'</p>';
 				} else {
 					$text = '<p style="color: red;">'.__('Empty Query', 'wp-dbmanager').'</p>';
diff --git a/wp-dbmanager.php b/wp-dbmanager.php
index f006082..96f7392 100644
--- a/wp-dbmanager.php
+++ b/wp-dbmanager.php
@@ -58,11 +58,10 @@ function dbmanager_menu() {
 add_filter('cron_schedules', 'cron_dbmanager_reccurences');
 add_action('dbmanager_cron_backup', 'cron_dbmanager_backup');
 add_action('dbmanager_cron_optimize', 'cron_dbmanager_optimize');
 add_action('dbmanager_cron_repair', 'cron_dbmanager_repair');
 function cron_dbmanager_backup() {
-	global $wpdb;
 	$backup_options = get_option('dbmanager_options');
 	$backup_email = stripslashes($backup_options['backup_email']);
 	if(intval($backup_options['backup_period']) > 0) {
 		$backup = array();
 		$backup['date'] = current_time('timestamp');
@@ -85,18 +84,18 @@ function cron_dbmanager_backup() {
 		$backup['command'] = '';
 		$brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
 		if(intval($backup_options['backup_gzip']) == 1) {
 			$backup['filename'] = $backup['date'].'_-_'.DB_NAME.'.sql.gz';
 			$backup['filepath'] = $backup['path'].'/'.$backup['filename'];
-			$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME.' | gzip > '.$brace.$backup['filepath'].$brace;
+			$backup['command'] = escapeshellcmd( $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME ). ' | gzip > '.escapeshellcmd( $brace.$backup['filepath'].$brace );
 		} else {
 			$backup['filename'] = $backup['date'].'_-_'.DB_NAME.'.sql';
 			$backup['filepath'] = $backup['path'].'/'.$backup['filename'];
-			$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME.' > '.$brace.$backup['filepath'].$brace;
+			$backup['command'] = escapeshellcmd( $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME ). ' > '.escapeshellcmd( $brace.$backup['filepath'].$brace );
 		}
 		execute_backup($backup['command']);
-		if( !empty( $backup_email ) )
+		if( ! empty( $backup_email ) )
 		{
 			dbmanager_email_backup( $backup_email, $backup['filepath'] );
 		}
 	}
 	return;
@@ -215,20 +214,20 @@ function execute_backup($command) {
 		return sprintf( __( '%s is not a valid mysqldump path', 'wp-dbmanager' ), stripslashes( $backup_options['mysqldumppath'] ) );
 	} else if( dbmanager_is_valid_path( $backup_options['mysqlpath'] ) === 0 ) {
 		return sprintf( __( '%s is not a valid mysql path', 'wp-dbmanager' ), stripslashes( $backup_options['mysqlpath'] ) );
 	}
 
-	if(substr(PHP_OS, 0, 3) == 'WIN') {
+	if( substr( PHP_OS, 0, 3 ) === 'WIN' ) {
 		$writable_dir = $backup_options['path'];
 		$tmpnam = $writable_dir.'/wp-dbmanager.bat';
-		$fp = fopen($tmpnam, 'w');
-		fwrite($fp, $command);
-		fclose($fp);
-		system($tmpnam.' > NUL', $error);
-		unlink($tmpnam);
+		$fp = fopen( $tmpnam, 'w' );
+		fwrite ($fp, $command );
+		fclose( $fp );
+		system( $tmpnam.' > NUL', $error );
+		unlink( $tmpnam );
 	} else {
-		passthru($command, $error);
+		passthru( $command, $error );
 	}
 	return $error;
 }
 
 ### Function: Check for valid file path

Vulnerable code: * FIXED: Use dbmanager_is_valid_path() to check for mysql and mysqldump path. Fixes arbitrary command injection using backup path. Props Larry W. Cashdollari.
* FIXED: Use realpath() to check for backup path. Fixes arbitrary command injection using backup path. Props Larry W. Cashdollari.
				$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' --add-drop-table --skip-lock-tables '.DB_NAME.' | gzip > '.$brace.$backup['filepath'].$brace;
				$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' --add-drop-table --skip-lock-tables '.DB_NAME.' > '.$brace.$backup['filepath'].$brace;
					$backup['command'] = 'gunzip < '.$brace.$backup['path'].'/'.$database_file.$brace.' | '.$brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME;
					$backup['command'] = $brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME.' < '.$brace.$backup['path'].'/'.$database_file.$brace;
					foreach($sql_queries as $sql_query) {
						if (preg_match("/^\\s*(insert|update|replace|delete|create|alter) /i",$sql_query)) {
							$run_query = $wpdb->query($sql_query);
							if(!$run_query) {
						} elseif (preg_match("/^\\s*(select|drop|show|grant) /i",$sql_query)) {
							$text .= "<p style=\"color: red;\">$sql_query</p>";
							$totalquerycount++;
	global $wpdb;
			$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME.' | gzip > '.$brace.$backup['filepath'].$brace;
			$backup['command'] = $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME.' > '.$brace.$backup['filepath'].$brace;
		if( !empty( $backup_email ) )
	if(substr(PHP_OS, 0, 3) == 'WIN') {
		$fp = fopen($tmpnam, 'w');
		fwrite($fp, $command);
		fclose($fp);
		system($tmpnam.' > NUL', $error);
		unlink($tmpnam);
		passthru($command, $error);
Fixed code: * FIXED: Uses escapeshellcmd() to escape shell commands
* FIXED: Do not allow LOAD_FILE to be run
* FIXED: Uses dbmanager_is_valid_path() to check for mysql and mysqldump path. Fixes arbitrary command injection using backup path. Props Larry W. Cashdollari.
* FIXED: Uses realpath() to check for backup path. Fixes arbitrary command injection using backup path. Props Larry W. Cashdollari.
				$backup['command'] = escapeshellcmd( $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' --add-drop-table --skip-lock-tables '.DB_NAME ).' | gzip > '.escapeshellcmd( $brace.$backup['filepath'].$brace );
				$backup['command'] = escapeshellcmd( $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' --add-drop-table --skip-lock-tables '.DB_NAME ).' > '.escapeshellcmd( $brace.$backup['filepath'].$brace );
					$backup['command'] = 'gunzip < '.escapeshellcmd( $brace.$backup['path'].'/'.$database_file.$brace ).' | '.escapeshellcmd( $brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME );
					$backup['command'] = escapeshellcmd( $brace.$backup['mysqlpath'].$brace.' --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].$backup['charset'].' '.DB_NAME ).' < '.escapeshellcmd( $brace.$backup['path'].'/'.$database_file.$brace );
					foreach( $sql_queries as $sql_query ) {
						if ( preg_match( "/LOAD_FILE/i", $sql_query ) ) {
							$text .= "<p style=\"color: red;\">$sql_query</p>";
							$totalquerycount++;
						} elseif( preg_match( "/^\\s*(select|drop|show|grant) /i", $sql_query ) ) {
							$text .= "<p style=\"color: red;\">$sql_query</p>";
							$totalquerycount++;
						} else if ( preg_match( "/^\\s*(insert|update|replace|delete|create|alter) /i", $sql_query ) ) {
							$run_query = $wpdb->query( $sql_query );
							if( ! $run_query ) {
			$backup['command'] = escapeshellcmd( $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME ). ' | gzip > '.escapeshellcmd( $brace.$backup['filepath'].$brace );
			$backup['command'] = escapeshellcmd( $brace.$backup['mysqldumppath'].$brace.' --force --host="'.$backup['host'].'" --user="'.DB_USER.'" --password="'.$backup['password'].'"'.$backup['port'].$backup['sock'].' --add-drop-table --skip-lock-tables '.DB_NAME ). ' > '.escapeshellcmd( $brace.$backup['filepath'].$brace );
		if( ! empty( $backup_email ) )
	if( substr( PHP_OS, 0, 3 ) === 'WIN' ) {
		$fp = fopen( $tmpnam, 'w' );
		fwrite ($fp, $command );
		fclose( $fp );
		system( $tmpnam.' > NUL', $error );
		unlink( $tmpnam );
		passthru( $command, $error );