Vulnerability: app/call_centers/cmd.php in the Call Center Queue Module in FusionPBX up to 4.5.7 suffers from a command injection vulnerability due to a lack of input validation, which allows authenticated attackers (with at least the permission call_center_queue_add or call_center_queue_edit) to execute any commands on the host as www-data.
Vulnerability ID: CVE-2019-16964
CWE: CWE-78
Severity score: 10
Project: https://github.com/fusionpbx/fusionpbx
Published: 2019-10-21
File: app/call_centers/cmd.php
Commit message: Update cmd.php
Commit author: FusionPBX

Vulnerable version (before fix):
  	The Initial Developer of the Original Code is 	Mark J Crane <markjcrane@fusionpbx.com> 	Portions created by the Initial Developer are Copyright (C) 2008-2012 	the Initial Developer. All Rights Reserved.  	Contributor(s): 	Mark J Crane <markjcrane@fusionpbx.com> */ include "root.php"; require_once "resources/require.php"; require_once "resources/check_auth.php"; if (permission_exists('call_center_queue_add') || permission_exists('call_center_queue_edit')) { 	//access granted } else { 	echo "access denied"; 	exit; }  $cmd = $_GET['cmd']; $rdr = $_GET['rdr'];  //connect to event socket $fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']); if ($fp) { 	$response = event_socket_request($fp, 'api reloadxml'); 	$response = event_socket_request($fp, $cmd); 	fclose($fp); } else { 	$response = ''; } if ($rdr == "false") { 	//redirect false 	echo $response; } else { 	$_SESSION["message"] = $response; 	header("Location: call_center_queues.php?savemsg=".urlencode($response)); } ?>\ No newline at end of file

Fixed version (after fix):
  	The Initial Developer of the Original Code is 	Mark J Crane <markjcrane@fusionpbx.com> 	Portions created by the Initial Developer are Copyright (C) 2008-2019 	the Initial Developer. All Rights Reserved.  	Contributor(s): 	Mark J Crane <markjcrane@fusionpbx.com> */  //includes 	include "root.php"; 	require_once "resources/require.php"; 	require_once "resources/check_auth.php";  //check permissions 	if (permission_exists('call_center_queue_add') || permission_exists('call_center_queue_edit')) { 		//access granted 	} 	else { 		echo "access denied"; 		exit; 	}  //get the variables 	$cmd = $_GET['cmd']; 	$queue = $_GET['queue'];  //validate the variables 	switch ($cmd) { 		case "load": 			//allow the command 			break; 		case "unload": 			//allow the command 			break; 		case "reload": 			//allow the command 			break; 		default: 			unset($cmd); 	}  //only allow a uuid for the queue name 	if (!is_uuid($queue)) { 		unset($queue); 	}  //connect to event socket 	$fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']); 	if ($fp) { 		$response = event_socket_request($fp, 'api reloadxml'); 		if (isset($cmd) && isset($queue)) { 			$response = event_socket_request($fp, 'api callcenter_config queue '.$cmd. ' '.$queue); 		} 		fclose($fp); 	} 	else { 		$response = ''; 	}  //send the redirect 	$_SESSION["message"] = $response; 	header("Location: call_center_queues.php?savemsg=".urlencode($response));\ No newline at end of file  ?>

Patch:
patch: @@ -17,42 +17,66 @@
 
 	The Initial Developer of the Original Code is
 	Mark J Crane <markjcrane@fusionpbx.com>
-	Portions created by the Initial Developer are Copyright (C) 2008-2012
+	Portions created by the Initial Developer are Copyright (C) 2008-2019
 	the Initial Developer. All Rights Reserved.
 
 	Contributor(s):
 	Mark J Crane <markjcrane@fusionpbx.com>
 */
-include "root.php";
-require_once "resources/require.php";
-require_once "resources/check_auth.php";
-if (permission_exists('call_center_queue_add') || permission_exists('call_center_queue_edit')) {
-	//access granted
-}
-else {
-	echo "access denied";
-	exit;
-}
-
-$cmd = $_GET['cmd'];
-$rdr = $_GET['rdr'];
+
+//includes
+	include "root.php";
+	require_once "resources/require.php";
+	require_once "resources/check_auth.php";
+
+//check permissions
+	if (permission_exists('call_center_queue_add') || permission_exists('call_center_queue_edit')) {
+		//access granted
+	}
+	else {
+		echo "access denied";
+		exit;
+	}
+
+//get the variables
+	$cmd = $_GET['cmd'];
+	$queue = $_GET['queue'];
+
+//validate the variables
+	switch ($cmd) {
+		case "load":
+			//allow the command
+			break;
+		case "unload":
+			//allow the command
+			break;
+		case "reload":
+			//allow the command
+			break;
+		default:
+			unset($cmd);
+	}
+
+//only allow a uuid for the queue name
+	if (!is_uuid($queue)) {
+		unset($queue);
+	}
 
 //connect to event socket
-$fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']);
-if ($fp) {
-	$response = event_socket_request($fp, 'api reloadxml');
-	$response = event_socket_request($fp, $cmd);
-	fclose($fp);
-}
-else {
-	$response = '';
-}
-if ($rdr == "false") {
-	//redirect false
-	echo $response;
-}
-else {
+	$fp = event_socket_create($_SESSION['event_socket_ip_address'], $_SESSION['event_socket_port'], $_SESSION['event_socket_password']);
+	if ($fp) {
+		$response = event_socket_request($fp, 'api reloadxml');
+		if (isset($cmd) && isset($queue)) {
+			$response = event_socket_request($fp, 'api callcenter_config queue '.$cmd. ' '.$queue);
+		}
+		fclose($fp);
+	}
+	else {
+		$response = '';
+	}
+
+//send the redirect
 	$_SESSION["message"] = $response;
 	header("Location: call_center_queues.php?savemsg=".urlencode($response));
-}
-?>
\ No newline at end of file
+
+?>
path: app/call_centers/cmd.php