Vulnerability: An issue was discovered in FusionPBX before 4.5.30. The fax_extension may have risky characters (it is not constrained to be numeric).
Vulnerability ID: CVE-2021-43405
CWE: CWE-20
Severity score: 6.4
Project: https://github.com/fusionpbx/fusionpbx
Published: 2021-11-05
File: app/fax/fax_send.php
Commit message: Require the fax_extension to be numeric.

Need to validate that the fax_extension really is numeric. Also replace event_socket_mkdir that makes a directory with mkdir.lua and use a php mkdir function instead. We want to offload this off of FreeSWITCH and its safer to use the PHP function.
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-2020 	the Initial Developer. All Rights Reserved.  	Contributor(s): 		$text = $language->get();  	//get the fax_extension and save it as a variable 		if (strlen($_REQUEST["fax_extension"]) > 0) { 			$fax_extension = $_REQUEST["fax_extension"]; 		}  function fax_split_dtmf(&$fax_number, &$fax_dtmf){ }  //get the fax extension 	if (strlen($fax_extension) > 0) { 		//set the fax directories. example /usr/local/freeswitch/storage/fax/329/inbox 			$dir_fax_inbox = $fax_dir.'/'.$fax_extension.'/inbox'; 			$dir_fax_sent = $fax_dir.'/'.$fax_extension.'/sent'; 			$dir_fax_temp = $fax_dir.'/'.$fax_extension.'/temp';  		//make sure the directories exist 			if (!is_dir($_SESSION['switch']['storage']['dir'])) { 				event_socket_mkdir($_SESSION['switch']['storage']['dir']); 			} 			if (!is_dir($_SESSION['switch']['storage']['dir'].'/fax')) { 				event_socket_mkdir($_SESSION['switch']['storage']['dir'].'/fax'); 			} 			if (!is_dir($_SESSION['switch']['storage']['dir'].'/fax/'.$_SESSION['domain_name'])) { 				event_socket_mkdir($_SESSION['switch']['storage']['dir'].'/fax/'.$_SESSION['domain_name']); 			} 			if (!is_dir($fax_dir.'/'.$fax_extension)) { 				event_socket_mkdir($fax_dir.'/'.$fax_extension); 			} 			if (!is_dir($dir_fax_inbox)) { 				event_socket_mkdir($dir_fax_inbox); 			} 			if (!is_dir($dir_fax_sent)) { 				event_socket_mkdir($dir_fax_sent); 			} 			if (!is_dir($dir_fax_temp)) { 				event_socket_mkdir($dir_fax_temp); 			} 	} 

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-2021 	the Initial Developer. All Rights Reserved.  	Contributor(s): 		$text = $language->get();  	//get the fax_extension and save it as a variable 		if (isset($_REQUEST["fax_extension"]) && is_numeric($_REQUEST["fax_extension"])) { 			$fax_extension = $_REQUEST["fax_extension"]; 		}  function fax_split_dtmf(&$fax_number, &$fax_dtmf){ }  //get the fax extension 	if (isset($fax_extension) && is_numeric($fax_extension)) { 		//set the fax directories. example /usr/local/freeswitch/storage/fax/329/inbox 			$dir_fax_inbox = $fax_dir.'/'.$fax_extension.'/inbox'; 			$dir_fax_sent = $fax_dir.'/'.$fax_extension.'/sent'; 			$dir_fax_temp = $fax_dir.'/'.$fax_extension.'/temp';  		//make sure the directories exist 			if (!is_dir($_SESSION['switch']['storage']['dir'])) { 				mkdir($_SESSION['switch']['storage']['dir'], 0770); 			} 			if (!is_dir($_SESSION['switch']['storage']['dir'].'/fax')) { 				mkdir($_SESSION['switch']['storage']['dir'].'/fax', 0770); 			} 			if (!is_dir($_SESSION['switch']['storage']['dir'].'/fax/'.$_SESSION['domain_name'])) { 				mkdir($_SESSION['switch']['storage']['dir'].'/fax/'.$_SESSION['domain_name'], 0770); 			} 			if (!is_dir($fax_dir.'/'.$fax_extension)) { 				mkdir($fax_dir.'/'.$fax_extension, 0770); 			} 			if (!is_dir($dir_fax_inbox)) { 				mkdir($dir_fax_inbox, 0770); 			} 			if (!is_dir($dir_fax_sent)) { 				mkdir($dir_fax_sent, 0770); 			} 			if (!is_dir($dir_fax_temp)) { 				mkdir($dir_fax_temp, 0770); 			} 	} 

Patch:
patch: @@ -17,7 +17,7 @@
 
 	The Initial Developer of the Original Code is
 	Mark J Crane <markjcrane@fusionpbx.com>
-	Portions created by the Initial Developer are Copyright (C) 2008-2020
+	Portions created by the Initial Developer are Copyright (C) 2008-2021
 	the Initial Developer. All Rights Reserved.
 
 	Contributor(s):
@@ -53,7 +53,7 @@
 		$text = $language->get();
 
 	//get the fax_extension and save it as a variable
-		if (strlen($_REQUEST["fax_extension"]) > 0) {
+		if (isset($_REQUEST["fax_extension"]) && is_numeric($_REQUEST["fax_extension"])) {
 			$fax_extension = $_REQUEST["fax_extension"];
 		}
 
@@ -214,33 +214,33 @@ function fax_split_dtmf(&$fax_number, &$fax_dtmf){
 }
 
 //get the fax extension
-	if (strlen($fax_extension) > 0) {
+	if (isset($fax_extension) && is_numeric($fax_extension)) {
 		//set the fax directories. example /usr/local/freeswitch/storage/fax/329/inbox
 			$dir_fax_inbox = $fax_dir.'/'.$fax_extension.'/inbox';
 			$dir_fax_sent = $fax_dir.'/'.$fax_extension.'/sent';
 			$dir_fax_temp = $fax_dir.'/'.$fax_extension.'/temp';
 
 		//make sure the directories exist
 			if (!is_dir($_SESSION['switch']['storage']['dir'])) {
-				event_socket_mkdir($_SESSION['switch']['storage']['dir']);
+				mkdir($_SESSION['switch']['storage']['dir'], 0770);
 			}
 			if (!is_dir($_SESSION['switch']['storage']['dir'].'/fax')) {
-				event_socket_mkdir($_SESSION['switch']['storage']['dir'].'/fax');
+				mkdir($_SESSION['switch']['storage']['dir'].'/fax', 0770);
 			}
 			if (!is_dir($_SESSION['switch']['storage']['dir'].'/fax/'.$_SESSION['domain_name'])) {
-				event_socket_mkdir($_SESSION['switch']['storage']['dir'].'/fax/'.$_SESSION['domain_name']);
+				mkdir($_SESSION['switch']['storage']['dir'].'/fax/'.$_SESSION['domain_name'], 0770);
 			}
 			if (!is_dir($fax_dir.'/'.$fax_extension)) {
-				event_socket_mkdir($fax_dir.'/'.$fax_extension);
+				mkdir($fax_dir.'/'.$fax_extension, 0770);
 			}
 			if (!is_dir($dir_fax_inbox)) {
-				event_socket_mkdir($dir_fax_inbox);
+				mkdir($dir_fax_inbox, 0770);
 			}
 			if (!is_dir($dir_fax_sent)) {
-				event_socket_mkdir($dir_fax_sent);
+				mkdir($dir_fax_sent, 0770);
 			}
 			if (!is_dir($dir_fax_temp)) {
-				event_socket_mkdir($dir_fax_temp);
+				mkdir($dir_fax_temp, 0770);
 			}
 	}
path: app/fax/fax_send.php