Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RCE vulnerability and add input validation #2440

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions htdocs/ajax.getAudioSink.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -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", "<b>enabled</b>", $btOutputs);
$btOutputs = str_replace("disabled", "<b>disabled</b>", $btOutputs);
Expand Down
18 changes: 14 additions & 4 deletions htdocs/ajax.getBluetoothStatus.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -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)";
}
}
Expand Down
39 changes: 24 additions & 15 deletions htdocs/ajax.loadInfo.php
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
<?php
include("inc.playerStatus.php");
$title = $playerStatus['title'];
$album = $playerStatus['album'];
$artist = $playerStatus['artist'];
$date = $playerStatus['date'];
$file = $playerStatus['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');
}

$title = sanitizeInput($playerStatus['title']);
$album = sanitizeInput($playerStatus['album']);
$artist = sanitizeInput($playerStatus['artist']);
$date = sanitizeInput($playerStatus['date']);
$file = sanitizeInput($playerStatus['file']);

if(trim($title) != "") {
print "<strong>".$title."</strong>";
print "<br><i>".str_replace(";", " and ", $artist)."</i>";
if (empty($album) != true) {
print "<br>".$album;
if (empty($date) != true) {
print " (".$date.")";
}
}
print "<strong>".$title."</strong>";
print "<br><i>".str_replace(";", " and ", $artist)."</i>";
if (empty($album) != true) {
print "<br>".$album;
if (empty($date) != true) {
print " (".$date.")";
}
}
} else {
print "<strong>".basename($file)."</strong>";
print "<strong>".basename($file)."</strong>";
}

?>
18 changes: 14 additions & 4 deletions htdocs/ajax.loadMPDStatus.php
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
<?php
$mpdstatus = exec("systemctl status mpd |grep 'Active: '|sed 's/Active: //g'");
?>
<div class="col-md-6"><?php echo trim($mpdstatus); ?></div>
<?php
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);
}

$mpdstatus = exec(sanitizeInput("systemctl status mpd |grep 'Active: '|sed 's/Active: //g'"));
?>
<div class="col-md-6"><?php echo trim($mpdstatus); ?></div>
28 changes: 19 additions & 9 deletions htdocs/ajax.loadMopidyStatus.php
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
<?php
$mopidyserverstatus = exec("echo -e status\\nclose | nc -w 1 localhost 6600 | grep 'OK MPD'| sed 's/^.*$/ACTIVE/'");
if ($mopidyserverstatus == "ACTIVE") {
$mopidystatus = "Mopidy.Server: Connected<br>Mopidy.Service: " . exec("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'");
} else {
$mopidystatus = "Mopidy.Server: Disconnected!<br>Mopidy.Service: " . exec("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'");
}
?>
<div class="col-md-6"><?php echo trim($mopidystatus); ?></div>
<?php
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);
}

$mopidyserverstatus = exec(sanitizeInput("echo -e status\\nclose | nc -w 1 localhost 6600 | grep 'OK MPD'| sed 's/^.*$/ACTIVE/'"));
if ($mopidyserverstatus == "ACTIVE") {
$mopidystatus = "Mopidy.Server: Connected<br>Mopidy.Service: " . exec(sanitizeInput("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'"));
} else {
$mopidystatus = "Mopidy.Server: Disconnected!<br>Mopidy.Service: " . exec(sanitizeInput("systemctl status mopidy | grep 'Active: '| sed 's/Active: //g'"));
}
?>
<div class="col-md-6"><?php echo trim($mopidystatus); ?></div>
21 changes: 17 additions & 4 deletions htdocs/ajax.loadOverallTime.php
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
<?php
include("inc.playerStatus.php");

if ( $playlistOverallTime > 0 && $playlistOverallTime < 3600 ) {
print '<span class="badge" style="float: right">'.date("i:s",$playlistPlayedTime).' / '.date("i:s",$playlistOverallTime).'</span>';
} elseif ( $playlistOverallTime > 0 ) {
print '<span class="badge" style="float: right">'.gmdate("H:i:s",$playlistPlayedTime).' / '.gmdate("H:i:s",$playlistOverallTime).'</span>';
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 '<span class="badge" style="float: right">' . date("i:s", $playlistPlayedTime) . ' / ' . date("i:s", $playlistOverallTime) . '</span>';
} elseif ($playlistOverallTime > 0) {
print '<span class="badge" style="float: right">' . gmdate("H:i:s", $playlistPlayedTime) . ' / ' . gmdate("H:i:s", $playlistOverallTime) . '</span>';
}
?>
13 changes: 12 additions & 1 deletion htdocs/ajax.refresh_id.php
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
<?php
include("config.php");

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');
}

$Audio_Folders_Path = trim(file_get_contents('../settings/Audio_Folders_Path'));
$Latest_Folder_Played = trim(file_get_contents('../settings/Latest_Folder_Played'));
$latestID = file_get_contents($conf['base_path'].'/shared/latestID.txt', true);
Expand All @@ -10,6 +21,6 @@
$dir = $Audio_Folders_Path."/".$shortcutready;

print "
<input id=\"cardID\" name=\"cardID\" placeholder=\"\" class=\"form-control input-md\" type=\"text\" value=\"".$onlyID."\">
<input id=\"cardID\" name=\"cardID\" placeholder=\"\" class=\"form-control input-md\" type=\"text\" value=\"".sanitizeInput($onlyID)."\">
";
?>
30 changes: 21 additions & 9 deletions htdocs/api/playlist/appendFileToPlaylist.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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);
}
}

?>
20 changes: 20 additions & 0 deletions htdocs/cardEdit.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 19 additions & 1 deletion htdocs/func.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
39 changes: 27 additions & 12 deletions htdocs/inc.bluetooth.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,35 @@
<i class='mdi mdi-volume-high'></i> <?php print $lang['globalAudioSink']; ?>
</h4>
<?php
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);
}

if(isset($_POST['btToggle'])) {
$btswitch = shell_exec($conf['scripts_abs']."/playout_controls.sh -c=bluetoothtoggle -v=toggle");
print "<br>";
print "<div class=\"row\">";
print " <div class=\"col-md-12\">";
if (strpos($btswitch, "Default") === false) {
print " <div class=\"alert alert-success\">";
} else {
print " <div class=\"alert alert-warning\">";
if (validateInput($_POST['btToggle'])) {
$sanitizedBtToggle = sanitizeInput($_POST['btToggle']);
$btswitch = shell_exec($conf['scripts_abs']."/playout_controls.sh -c=bluetoothtoggle -v=toggle");
print "<br>";
print "<div class=\"row\">";
print " <div class=\"col-md-12\">";
if (strpos($btswitch, "Default") === false) {
print " <div class=\"alert alert-success\">";
} else {
print " <div class=\"alert alert-warning\">";
}
print "Message: $btswitch</div>";
print " </div>";
print "</div>";
} else {
http_response_code(400);
echo "Invalid input.";
}
print "Message: $btswitch</div>";
print " </div>";
print "</div>";
}
?>
</div><!-- /.panel-heading -->
Expand All @@ -64,4 +80,3 @@
</div><!-- /.panel-body -->
</div><!-- /.panel panel-default-->
</div><!-- /.panel-group -->

36 changes: 36 additions & 0 deletions htdocs/inc.controlPlayer.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,39 @@
include('inc.loadControls.php');
?>
</div>

<?php
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 ($_GET as $key => $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;
}
}
?>
Loading
Loading