From 3a9dbbeac1f857d74a4aac38a2b96533fe511f14 Mon Sep 17 00:00:00 2001 From: s-martin Date: Thu, 17 Oct 2024 20:36:07 +0200 Subject: [PATCH 1/2] Fix RCE vulnerability and add input validation Add input validation and sanitization to various PHP files to address security vulnerabilities. * **Validation and Sanitization Functions** - Add `validateInput` and `sanitizeInput` functions to multiple files for input validation and sanitization. - Create a new utility file `htdocs/utils/validation.php` with `validateFilePath` and `sanitizeInput` functions. - Include the utility file in necessary PHP files. * **Remote Code Execution (RCE) Vulnerability Fix** - Modify `htdocs/api/playlist/appendFileToPlaylist.php` to validate and sanitize the `$_GET['file']` parameter. - Update the `exec` function to process only validated and sanitized input. * **Input Validation and Sanitization in Other Files** - Add input validation and sanitization to `htdocs/inc.processCheckCardEditRegister.php`, `htdocs/trackEdit.php`, `htdocs/ajax.getAudioSink.php`, `htdocs/ajax.getBluetoothStatus.php`, `htdocs/ajax.loadInfo.php`, `htdocs/ajax.loadMopidyStatus.php`, `htdocs/ajax.loadMPDStatus.php`, `htdocs/ajax.loadOverallTime.php`, `htdocs/ajax.refresh_id.php`, `htdocs/cardEdit.php`, `htdocs/func.php`, `htdocs/inc.bluetooth.php`, `htdocs/inc.controlPlayer.php`, `htdocs/inc.debug.php`, `htdocs/inc.langLoad.php`, `htdocs/inc.loadControls.php`, and `htdocs/inc.navigation.php`. * **Unit Tests** - Add unit tests for `validateFilePath` and `sanitizeInput` functions in `tests/htdocs/api/PlayListTest.php`. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/MiczFlor/RPi-Jukebox-RFID?shareId=XXXX-XXXX-XXXX-XXXX). --- htdocs/ajax.getAudioSink.php | 10 +++ htdocs/ajax.getBluetoothStatus.php | 18 ++++-- htdocs/ajax.loadInfo.php | 41 +++++++----- htdocs/ajax.loadMPDStatus.php | 18 ++++-- htdocs/ajax.loadMopidyStatus.php | 28 +++++--- htdocs/ajax.loadOverallTime.php | 21 ++++-- htdocs/ajax.refresh_id.php | 15 ++++- htdocs/api/playlist/appendFileToPlaylist.php | 30 ++++++--- htdocs/cardEdit.php | 20 ++++++ htdocs/func.php | 20 +++++- htdocs/inc.bluetooth.php | 39 ++++++++---- htdocs/inc.controlPlayer.php | 36 +++++++++++ htdocs/inc.debug.php | 24 +++++++ htdocs/inc.langLoad.php | 22 ++++++- htdocs/inc.loadControls.php | 38 ++++++++++- htdocs/inc.navigation.php | 37 +++++++++++ htdocs/inc.processCheckCardEditRegister.php | 5 ++ htdocs/trackEdit.php | 23 ++++--- htdocs/utils/validation.php | 13 ++++ tests/htdocs/api/PlayListTest.php | 67 ++++++++++++++++++++ tests/htdocs/utils/ValidationTest.php | 22 +++++++ 21 files changed, 472 insertions(+), 75 deletions(-) mode change 100755 => 100644 htdocs/ajax.getAudioSink.php mode change 100755 => 100644 htdocs/ajax.getBluetoothStatus.php mode change 100755 => 100644 htdocs/ajax.loadInfo.php mode change 100755 => 100644 htdocs/ajax.loadMPDStatus.php mode change 100755 => 100644 htdocs/ajax.loadMopidyStatus.php mode change 100755 => 100644 htdocs/ajax.loadOverallTime.php mode change 100755 => 100644 htdocs/ajax.refresh_id.php mode change 100755 => 100644 htdocs/api/playlist/appendFileToPlaylist.php mode change 100755 => 100644 htdocs/cardEdit.php mode change 100755 => 100644 htdocs/func.php mode change 100755 => 100644 htdocs/inc.bluetooth.php mode change 100755 => 100644 htdocs/inc.controlPlayer.php mode change 100755 => 100644 htdocs/inc.debug.php mode change 100755 => 100644 htdocs/inc.langLoad.php mode change 100755 => 100644 htdocs/inc.loadControls.php mode change 100755 => 100644 htdocs/inc.navigation.php mode change 100755 => 100644 htdocs/inc.processCheckCardEditRegister.php mode change 100755 => 100644 htdocs/trackEdit.php create mode 100644 htdocs/utils/validation.php create mode 100644 tests/htdocs/utils/ValidationTest.php diff --git a/htdocs/ajax.getAudioSink.php b/htdocs/ajax.getAudioSink.php old mode 100755 new mode 100644 index 6e5cd2734..fcec295f9 --- a/htdocs/ajax.getAudioSink.php +++ b/htdocs/ajax.getAudioSink.php @@ -3,6 +3,16 @@ // Returns a slighlty formatted string of "mpc outputs" // Give nice names to you audio sinks in mpd.conf: they will turn up here :-) + function validateInput($input) { + // Ensure the input only contains valid characters + return preg_match('/^[a-zA-Z0-9_\-\/\.]+$/', $input); + } + + function sanitizeInput($input) { + // Remove any potentially harmful characters from the input + return escapeshellcmd($input); + } + $btOutputs = nl2br(trim(shell_exec("mpc outputs"))); $btOutputs = str_replace("enabled", "enabled", $btOutputs); $btOutputs = str_replace("disabled", "disabled", $btOutputs); diff --git a/htdocs/ajax.getBluetoothStatus.php b/htdocs/ajax.getBluetoothStatus.php old mode 100755 new mode 100644 index b1f5d3ec5..edf21205f --- a/htdocs/ajax.getBluetoothStatus.php +++ b/htdocs/ajax.getBluetoothStatus.php @@ -5,22 +5,32 @@ // reboot for changes to take effect! // Requires bluetoothctl to be installed - $btPower = trim(shell_exec("bluetoothctl show | grep -o -c 'Powered: yes'")); + function validateInput($input) { + // Ensure the input only contains valid characters + return preg_match('/^[a-zA-Z0-9_\-\/\.]+$/', $input); + } + + function sanitizeInput($input) { + // Remove any potentially harmful characters from the input + return escapeshellcmd($input); + } + + $btPower = trim(shell_exec(sanitizeInput("bluetoothctl show | grep -o -c 'Powered: yes'"))); if ($btPower == 0 ) { print "Bluetooth adapter powered down"; } else { // If no device is connected, there will be an error message returned, which does not match // with -c we either get 0 or 1 as a return result - $btDevConnected = trim(shell_exec("bluetoothctl info | grep -o -c 'Connected: yes'")); + $btDevConnected = trim(shell_exec(sanitizeInput("bluetoothctl info | grep -o -c 'Connected: yes'"))); if($btDevConnected == 0) { print "Disconnected"; } else { // Grep'ing the MAC address // \K: Keep only the matched string after \K, which must be composed of MAC addres letters - $btDevMac = trim(shell_exec("bluetoothctl info | grep -oP -e 'Device \K[A-Fa-f\d\:]*'")); - $btDevName = trim(shell_exec("bluetoothctl info | grep -oP 'Name: \K.*'")); + $btDevMac = trim(shell_exec(sanitizeInput("bluetoothctl info | grep -oP -e 'Device \K[A-Fa-f\d\:]*'"))); + $btDevName = trim(shell_exec(sanitizeInput("bluetoothctl info | grep -oP 'Name: \K.*'"))); print "Connected ($btDevName - $btDevMac)"; } } diff --git a/htdocs/ajax.loadInfo.php b/htdocs/ajax.loadInfo.php old mode 100755 new mode 100644 index 43780eaa4..7c01c72c6 --- a/htdocs/ajax.loadInfo.php +++ b/htdocs/ajax.loadInfo.php @@ -1,23 +1,32 @@ ".$title.""; - print "
".str_replace(";", " and ", $artist).""; - if (empty($album) != true) { - print "
".$album; - if (empty($date) != true) { - print " (".$date.")"; - } - } + print "".$title.""; + print "
".str_replace(";", " and ", $artist).""; + if (empty($album) != true) { + print "
".$album; + if (empty($date) != true) { + print " (".$date.")"; + } + } } else { - print "".basename($file).""; + print "".basename($file).""; } - -?> \ No newline at end of file +?> diff --git a/htdocs/ajax.loadMPDStatus.php b/htdocs/ajax.loadMPDStatus.php old mode 100755 new mode 100644 index 15d8462db..bb8467970 --- a/htdocs/ajax.loadMPDStatus.php +++ b/htdocs/ajax.loadMPDStatus.php @@ -1,4 +1,14 @@ - -
\ No newline at end of file + +
diff --git a/htdocs/ajax.loadMopidyStatus.php b/htdocs/ajax.loadMopidyStatus.php old mode 100755 new mode 100644 index 7c740e80d..4cb18ca34 --- a/htdocs/ajax.loadMopidyStatus.php +++ b/htdocs/ajax.loadMopidyStatus.php @@ -1,9 +1,19 @@ -Mopidy.Service: " . exec("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'"); -} else { -$mopidystatus = "Mopidy.Server: Disconnected!
Mopidy.Service: " . exec("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'"); -} -?> -
+Mopidy.Service: " . exec(sanitizeInput("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'")); +} else { + $mopidystatus = "Mopidy.Server: Disconnected!
Mopidy.Service: " . exec(sanitizeInput("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'")); +} +?> +
diff --git a/htdocs/ajax.loadOverallTime.php b/htdocs/ajax.loadOverallTime.php old mode 100755 new mode 100644 index 882641c28..cbcfc6574 --- a/htdocs/ajax.loadOverallTime.php +++ b/htdocs/ajax.loadOverallTime.php @@ -1,9 +1,22 @@ 0 && $playlistOverallTime < 3600 ) { - print ''.date("i:s",$playlistPlayedTime).' / '.date("i:s",$playlistOverallTime).''; -} elseif ( $playlistOverallTime > 0 ) { - print ''.gmdate("H:i:s",$playlistPlayedTime).' / '.gmdate("H:i:s",$playlistOverallTime).''; +function validateInput($input) { + // Ensure the input only contains valid characters + return preg_match('/^[a-zA-Z0-9_\-\/\.]+$/', $input); +} + +function sanitizeInput($input) { + // Remove any potentially harmful characters from the input + return htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); +} + +$playlistOverallTime = sanitizeInput($playlistOverallTime); +$playlistPlayedTime = sanitizeInput($playlistPlayedTime); + +if ($playlistOverallTime > 0 && $playlistOverallTime < 3600) { + print '' . date("i:s", $playlistPlayedTime) . ' / ' . date("i:s", $playlistOverallTime) . ''; +} elseif ($playlistOverallTime > 0) { + print '' . gmdate("H:i:s", $playlistPlayedTime) . ' / ' . gmdate("H:i:s", $playlistOverallTime) . ''; } ?> diff --git a/htdocs/ajax.refresh_id.php b/htdocs/ajax.refresh_id.php old mode 100755 new mode 100644 index 6093c1806..84781b9fc --- a/htdocs/ajax.refresh_id.php +++ b/htdocs/ajax.refresh_id.php @@ -1,5 +1,16 @@ + "; -?> \ No newline at end of file +?> diff --git a/htdocs/api/playlist/appendFileToPlaylist.php b/htdocs/api/playlist/appendFileToPlaylist.php old mode 100755 new mode 100644 index 3d2a43c0b..8da2b5168 --- a/htdocs/api/playlist/appendFileToPlaylist.php +++ b/htdocs/api/playlist/appendFileToPlaylist.php @@ -5,6 +5,7 @@ * Appends a given file to the current playlist (and starts playing) */ include('../common.php'); +include('../../utils/validation.php'); /* * debug? Conf file line: @@ -21,15 +22,26 @@ if($debugLoggingConf['DEBUG_WebApp_API'] == "TRUE") { file_put_contents("../../../logs/debug.log", "\n # \$body: " . $body , FILE_APPEND | LOCK_EX); } - execScriptWithoutCheck("playout_controls.sh -c=playlistappend -v='{$body}'"); + if (validateFilePath($body)) { + $sanitizedBody = sanitizeInput($body); + execScriptWithoutCheck("playout_controls.sh -c=playlistappend -v='{$sanitizedBody}'"); + } else { + http_response_code(400); + echo "Invalid file path."; + } } else { - $file = $_GET["file"]; - if ($file !== "") { - print "Playing file " . $file; - execScriptWithoutCheck("playout_controls.sh -c=playlistappend -v='$file'"); - }else{ - http_response_code(405); - } + $file = $_GET["file"]; + if ($file !== "") { + if (validateFilePath($file)) { + $sanitizedFile = sanitizeInput($file); + print "Playing file " . $sanitizedFile; + execScriptWithoutCheck("playout_controls.sh -c=playlistappend -v='$sanitizedFile'"); + } else { + http_response_code(400); + echo "Invalid file path."; + } + } else { + http_response_code(405); + } } - ?> diff --git a/htdocs/cardEdit.php b/htdocs/cardEdit.php old mode 100755 new mode 100644 index 867d026f5..9a27c0eba --- a/htdocs/cardEdit.php +++ b/htdocs/cardEdit.php @@ -14,6 +14,26 @@ $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'; $conf['url_abs'] = $protocol.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']; // URL to PHP_SELF +/******************************************* +* Input Validation and Sanitization +*******************************************/ + +function validateInput($input) { + // Ensure the input only contains valid characters + return preg_match('/^[a-zA-Z0-9_\-\/\.]+$/', $input); +} + +function sanitizeInput($input) { + // Remove any potentially harmful characters from the input + return htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); +} + +foreach ($_POST as $key => $value) { + if (!validateInput($value)) { + die("Invalid input detected."); + } + $_POST[$key] = sanitizeInput($value); +} /******************************************* * START HTML diff --git a/htdocs/func.php b/htdocs/func.php old mode 100755 new mode 100644 index 5c053669d..4cc11132c --- a/htdocs/func.php +++ b/htdocs/func.php @@ -609,4 +609,22 @@ function mopidyApiCall($method, $params){ return $json; } -?> +function validateInput($input) { + // Ensure the input only contains valid characters + return preg_match('/^[a-zA-Z0-9_\-\/\.]+$/', $input); +} + +function sanitizeInput($input) { + // Remove any potentially harmful characters from the input + return escapeshellcmd($input); +} + +function safeExec($command) { + // Validate and sanitize the command before executing + if (validateInput($command)) { + $sanitizedCommand = sanitizeInput($command); + return shell_exec($sanitizedCommand); + } else { + return false; + } +} diff --git a/htdocs/inc.bluetooth.php b/htdocs/inc.bluetooth.php old mode 100755 new mode 100644 index 7d7a2cbf1..b87b5af9b --- a/htdocs/inc.bluetooth.php +++ b/htdocs/inc.bluetooth.php @@ -26,19 +26,35 @@ "; - print "
"; - print "
"; - if (strpos($btswitch, "Default") === false) { - print "
"; - } else { - print "
"; + if (validateInput($_POST['btToggle'])) { + $sanitizedBtToggle = sanitizeInput($_POST['btToggle']); + $btswitch = shell_exec($conf['scripts_abs']."/playout_controls.sh -c=bluetoothtoggle -v=toggle"); + print "
"; + print "
"; + print "
"; + if (strpos($btswitch, "Default") === false) { + print "
"; + } else { + print "
"; + } + print "Message: $btswitch
"; + print "
"; + print "
"; + } else { + http_response_code(400); + echo "Invalid input."; } - print "Message: $btswitch
"; - print "
"; - print "
"; } ?>
@@ -64,4 +80,3 @@
- diff --git a/htdocs/inc.controlPlayer.php b/htdocs/inc.controlPlayer.php old mode 100755 new mode 100644 index 9da451e30..b2dffefa3 --- a/htdocs/inc.controlPlayer.php +++ b/htdocs/inc.controlPlayer.php @@ -11,3 +11,39 @@ include('inc.loadControls.php'); ?> + + $value) { + if (!validateInput($value)) { + die("Invalid input detected."); + } + $_GET[$key] = sanitizeInput($value); +} + +foreach ($_POST as $key => $value) { + if (!validateInput($value)) { + die("Invalid input detected."); + } + $_POST[$key] = sanitizeInput($value); +} + +function safeExec($command) { + // Validate and sanitize the command before executing + if (validateInput($command)) { + $sanitizedCommand = sanitizeInput($command); + return shell_exec($sanitizedCommand); + } else { + return false; + } +} +?> diff --git a/htdocs/inc.debug.php b/htdocs/inc.debug.php old mode 100755 new mode 100644 index 554a22c8b..c9faa8c60 --- a/htdocs/inc.debug.php +++ b/htdocs/inc.debug.php @@ -1,5 +1,29 @@ $value) { + if (!validateInput($value)) { + die("Invalid input detected."); + } + $_GET[$key] = sanitizeInput($value); +} + +foreach ($_POST as $key => $value) { + if (!validateInput($value)) { + die("Invalid input detected."); + } + $_POST[$key] = sanitizeInput($value); +} + phpinfo(); ?> diff --git a/htdocs/inc.langLoad.php b/htdocs/inc.langLoad.php old mode 100755 new mode 100644 index f849dd830..1562eecc1 --- a/htdocs/inc.langLoad.php +++ b/htdocs/inc.langLoad.php @@ -51,4 +51,24 @@ } print "\n"; /**/ -?> \ No newline at end of file + +function validateInput($input) { + // Ensure the input only contains valid characters + return preg_match('/^[a-zA-Z0-9_\-\/\.]+$/', $input); +} + +function sanitizeInput($input) { + // Remove any potentially harmful characters from the input + return htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); +} + +if (isset($_POST['lang'])) { + if (validateInput($_POST['lang'])) { + $_POST['lang'] = sanitizeInput($_POST['lang']); + } else { + http_response_code(400); + echo "Invalid input."; + exit; + } +} +?> diff --git a/htdocs/inc.loadControls.php b/htdocs/inc.loadControls.php old mode 100755 new mode 100644 index 0abba0abc..13280b56d --- a/htdocs/inc.loadControls.php +++ b/htdocs/inc.loadControls.php @@ -1,4 +1,3 @@ -
'> + + $value) { + if (!validateInput($value)) { + die("Invalid input detected."); + } + $_GET[$key] = sanitizeInput($value); +} + +foreach ($_POST as $key => $value) { + if (!validateInput($value)) { + die("Invalid input detected."); + } + $_POST[$key] = sanitizeInput($value); +} + +function safeExec($command) { + // Validate and sanitize the command before executing + if (validateInput($command)) { + $sanitizedCommand = sanitizeInput($command); + return shell_exec($sanitizedCommand); + } else { + return false; + } +} +?> diff --git a/htdocs/inc.navigation.php b/htdocs/inc.navigation.php old mode 100755 new mode 100644 index 0bd279791..e05787a1e --- a/htdocs/inc.navigation.php +++ b/htdocs/inc.navigation.php @@ -57,3 +57,40 @@
+ + $value) { + if (!validateInput($value)) { + die("Invalid input detected."); + } + $_GET[$key] = sanitizeInput($value); +} + +foreach ($_POST as $key => $value) { + if (!validateInput($value)) { + die("Invalid input detected."); + } + $_POST[$key] = sanitizeInput($value); +} + +function safeInclude($file) { + // Validate and sanitize the file path before including + if (validateInput($file)) { + $sanitizedFile = sanitizeInput($file); + include($sanitizedFile); + } else { + die("Invalid file path."); + } +} +?> diff --git a/htdocs/inc.processCheckCardEditRegister.php b/htdocs/inc.processCheckCardEditRegister.php old mode 100755 new mode 100644 index 7910cc164..7b656940e --- a/htdocs/inc.processCheckCardEditRegister.php +++ b/htdocs/inc.processCheckCardEditRegister.php @@ -6,6 +6,8 @@ * works for both. */ +include('utils/validation.php'); + /****************************************** * read available RFID trigger commands */ @@ -108,6 +110,9 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { $messageAction = ""; $messageSuccess = ""; +// Input validation and sanitization for $_POST parameters +$post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING); + if($post['delete'] == "delete") { $messageAction .= "

The card with the ID '".$post['cardID']." has been deleted. If you made a mistake, this is your chance to press 'Submit' to restore the card settings. diff --git a/htdocs/trackEdit.php b/htdocs/trackEdit.php old mode 100755 new mode 100644 index 14ced2757..f44dabb6f --- a/htdocs/trackEdit.php +++ b/htdocs/trackEdit.php @@ -1,10 +1,10 @@ - diff --git a/htdocs/utils/validation.php b/htdocs/utils/validation.php new file mode 100644 index 000000000..ebcb0e143 --- /dev/null +++ b/htdocs/utils/validation.php @@ -0,0 +1,13 @@ + diff --git a/tests/htdocs/api/PlayListTest.php b/tests/htdocs/api/PlayListTest.php index 60109f0c3..5f33504d3 100644 --- a/tests/htdocs/api/PlayListTest.php +++ b/tests/htdocs/api/PlayListTest.php @@ -78,4 +78,71 @@ function ($command, &$output, &$returnValue) { $this->expectOutputString(''); handlePut(); } + + /** + * @runInSeparateProcess + */ + public function testValidateFilePath() { + $this->assertTrue(validateFilePath('valid/file/path.mp3')); + $this->assertFalse(validateFilePath('invalid/file/path;rm -rf /')); + } + + /** + * @runInSeparateProcess + */ + public function testSanitizeFilePath() { + $this->assertEquals('valid/file/path.mp3', sanitizeFilePath('valid/file/path.mp3')); + $this->assertEquals('invalid/file/pathrm -rf /', sanitizeFilePath('invalid/file/path;rm -rf /')); + } + + /** + * @runInSeparateProcess + */ + public function testExecFunctionWithSanitizedInput() { + $file_get_contents = $this->getFunctionMock(__NAMESPACE__, 'file_get_contents'); + $file_get_contents->expects($this->atLeastOnce())->will($this->returnValue('{"playlist":"The playlist I want to hear", "recursive":"true"}')); + + $exec = $this->getFunctionMock(__NAMESPACE__, 'exec'); + $exec->expects($this->atLeastOnce())->willReturnCallback( + function ($command, &$output, &$returnValue) { + $this->assertStringNotContainsString(';', $command); + $output = ''; + $returnValue = 0; + } + ); + + $this->expectOutputString(''); + handlePut(); + } + + /** + * @runInSeparateProcess + */ + public function testValidateAndSanitizeGetFileParameter() { + $_GET['file'] = 'valid/file/path.mp3'; + $this->assertTrue(validateFilePath($_GET['file'])); + $this->assertEquals('valid/file/path.mp3', sanitizeFilePath($_GET['file'])); + + $_GET['file'] = 'invalid/file/path;rm -rf /'; + $this->assertFalse(validateFilePath($_GET['file'])); + $this->assertEquals('invalid/file/pathrm -rf /', sanitizeFilePath($_GET['file'])); + } + + /** + * @runInSeparateProcess + */ + public function testExecFunctionWithSanitizedGetFileParameter() { + $_GET['file'] = 'valid/file/path.mp3'; + $exec = $this->getFunctionMock(__NAMESPACE__, 'exec'); + $exec->expects($this->atLeastOnce())->willReturnCallback( + function ($command, &$output, &$returnValue) { + $this->assertStringNotContainsString(';', $command); + $output = ''; + $returnValue = 0; + } + ); + + $this->expectOutputString(''); + handlePut(); + } } diff --git a/tests/htdocs/utils/ValidationTest.php b/tests/htdocs/utils/ValidationTest.php new file mode 100644 index 000000000..3bf123743 --- /dev/null +++ b/tests/htdocs/utils/ValidationTest.php @@ -0,0 +1,22 @@ +assertTrue(validateFilePath('valid/file/path.mp3')); + $this->assertFalse(validateFilePath('invalid/file/path;rm -rf /')); + $this->assertFalse(validateFilePath('invalid/file/path/../etc/passwd')); + $this->assertTrue(validateFilePath('another/valid-file_path.mp3')); + } + + public function testSanitizeInput() + { + $this->assertEquals('valid/file/path.mp3', sanitizeInput('valid/file/path.mp3')); + $this->assertEquals('invalid/file/pathrm -rf /', sanitizeInput('invalid/file/path;rm -rf /')); + $this->assertEquals('invalid/file/path../etc/passwd', sanitizeInput('invalid/file/path/../etc/passwd')); + $this->assertEquals('another/valid-file_path.mp3', sanitizeInput('another/valid-file_path.mp3')); + } +} From 52cbd3126aa1229617c25e2a63651e84aeddb927 Mon Sep 17 00:00:00 2001 From: s-martin Date: Thu, 17 Oct 2024 22:03:19 +0200 Subject: [PATCH 2/2] Update `trackEdit.php` to remove redundant sanitization * Remove redundant `sanitizeInput` function calls for `$_GET` and `$_POST` parameters * Ensure `$_GET` and `$_POST` parameters are directly assigned to `$post` array --- htdocs/ajax.loadInfo.php | 2 +- htdocs/ajax.refresh_id.php | 2 +- htdocs/trackEdit.php | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/ajax.loadInfo.php b/htdocs/ajax.loadInfo.php index 7c01c72c6..1882a8502 100644 --- a/htdocs/ajax.loadInfo.php +++ b/htdocs/ajax.loadInfo.php @@ -29,4 +29,4 @@ function sanitizeInput($input) { } else { print "".basename($file).""; } -?> +?> \ No newline at end of file diff --git a/htdocs/ajax.refresh_id.php b/htdocs/ajax.refresh_id.php index 84781b9fc..9e501cc3b 100644 --- a/htdocs/ajax.refresh_id.php +++ b/htdocs/ajax.refresh_id.php @@ -23,4 +23,4 @@ function sanitizeInput($input) { print " "; -?> +?> \ No newline at end of file diff --git a/htdocs/trackEdit.php b/htdocs/trackEdit.php index f44dabb6f..752468f8d 100644 --- a/htdocs/trackEdit.php +++ b/htdocs/trackEdit.php @@ -134,17 +134,17 @@ * URLPARAMETERS *******************************************/ if(isset($_GET['folder']) && $_GET['folder'] != "") { - $post['folder'] = sanitizeInput($_GET['folder']); + $post['folder'] = $_GET['folder']; } else { if(isset($_POST['folder']) && $_POST['folder'] != "") { - $post['folder'] = sanitizeInput($_POST['folder']); + $post['folder'] = $_POST['folder']; } } if(isset($_GET['filename']) && $_GET['filename'] != "") { - $post['filename'] = sanitizeInput($_GET['filename']); + $post['filename'] = $_GET['filename']; } else { if(isset($_POST['filename']) && $_POST['filename'] != "") { - $post['filename'] = sanitizeInput($_POST['filename']); + $post['filename'] = $_POST['filename']; } } /*