Skip to content
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
2 changes: 1 addition & 1 deletion ajax/networking/do_sys_reset.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
try {
$tmp = file_get_contents($config["src"]);
file_put_contents($config["tmp"], $tmp);
system("sudo cp ".$config["tmp"]. " ".$config["dest"]);
system("sudo cp ".escapeshellarg($config["tmp"]). " ".escapeshellarg($config["dest"]));
} catch (Exception $e) {
$return = $e->getCode();
}
Expand Down
2 changes: 1 addition & 1 deletion ajax/networking/get_ip_summary.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

if (isset($_POST['interface'])) {
$int = preg_replace('/[^a-z0-9]/', '', $_POST['interface']);
exec('ip a s '.$int, $intOutput, $intResult);
exec('ip a s '.escapeshellarg($int), $intOutput, $intResult);
$intOutput = array_map('htmlentities', $intOutput);
$jsonData = ['return'=>$intResult,'output'=>$intOutput];
echo json_encode($jsonData);
Expand Down
2 changes: 1 addition & 1 deletion ajax/networking/get_netcfg.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
require_once '../../includes/authenticate.php';
require_once '../../includes/functions.php';

$interface = $_POST['iface'];
$interface = escapeshellarg($_POST['iface']);

if (isset($interface)) {
// fetch dnsmasq.conf settings for interface
Expand Down
2 changes: 1 addition & 1 deletion includes/configure_client.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function DisplayWPAConfig()

if (preg_match('/delete(\d+)/', $post, $post_match)) {
$network = $tmp_networks[$_POST['ssid' . $post_match[1]]];
$netid = $network['index'];
$netid = intval($network['index']);
exec('sudo wpa_cli -i ' . $iface . ' disconnect ' . $netid);
exec('sudo wpa_cli -i ' . $iface . ' remove_network ' . $netid);
unset($tmp_networks[$_POST['ssid' . $post_match[1]]]);
Expand Down
18 changes: 14 additions & 4 deletions includes/dhcp.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ function DisplayDHCPConfig()
function saveDHCPConfig($status)
{
$iface = $_POST['interface'];
if (!validateInterface($iface)) {
$status->addMessage('Invalid interface name provided.', 'danger');
return false;
}
$return = 1;

// handle disable dhcp option
Expand Down Expand Up @@ -140,7 +144,7 @@ function validateDHCPInput()
$errors = [];
define('IFNAMSIZ', 16);
$iface = $_POST['interface'];
if (!preg_match('/^[^\s\/\\0]+$/', $iface)
if (!preg_match('/^[a-zA-Z0-9_-]+$/', $iface)
|| strlen($iface) >= IFNAMSIZ
) {
$errors[] = _('Invalid interface name.');
Expand Down Expand Up @@ -273,7 +277,9 @@ function updateDnsmasqConfig($iface,$status)
}
file_put_contents("/tmp/dnsmasqdata", $config);
$msg = file_exists(RASPI_DNSMASQ_PREFIX.$iface.'.conf') ? 'updated' : 'added';
system('sudo cp /tmp/dnsmasqdata '.RASPI_DNSMASQ_PREFIX.$iface.'.conf', $result);
$destination = RASPI_DNSMASQ_PREFIX . escapeshellarg($iface . '.conf');
$command = sprintf('sudo cp /tmp/dnsmasqdata %s', $destination);
system($command, $result);
if ($result == 0) {
$status->addMessage('Dnsmasq configuration for '.$iface.' '.$msg.'.', 'success');
}
Expand All @@ -291,7 +297,9 @@ function updateDnsmasqConfig($iface,$status)
}
$config .= PHP_EOL;
file_put_contents("/tmp/dnsmasqdata", $config);
system('sudo cp /tmp/dnsmasqdata '.RASPI_DNSMASQ_PREFIX.'raspap.conf', $result);
$destination = escapeshellarg(RASPI_DNSMASQ_PREFIX . 'raspap.conf');
$command = sprintf('sudo cp /tmp/dnsmasqdata %s', $destination);
system($command, $result);

return $result;
}
Expand Down Expand Up @@ -340,7 +348,9 @@ function updateDHCPConfig($iface,$status)
$status->addMessage('DHCP configuration for '.$iface.' updated.', 'success');
}
file_put_contents("/tmp/dhcpddata", $dhcp_cfg);
system('sudo cp /tmp/dhcpddata '.RASPI_DHCPCD_CONFIG, $result);
$destination = escapeshellarg(RASPI_DHCPCD_CONFIG);
$command = sprintf('sudo cp /tmp/dhcpddata %s', $destination);
system($command, $result);

return $result;
}
Expand Down
38 changes: 19 additions & 19 deletions includes/get_clients.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ function getClients($simple=true)
if (empty(preg_only_match("/(ppp)[0-9]/", $rawdevs))) {
if (!empty($devtty)) {
$rawdevs[]="ppp0";
exec("udevadm info --name='$devtty' 2> /dev/null");
exec("udevadm info --name=".escapeshellarg($devtty)." 2> /dev/null");
}
}
foreach ($rawdevs as $i => $dev) {
$cl["device"][$i]["name"]=$dev;
$nam = (preg_match("/^(\w+)[0-9]$/",$dev,$nam) === 1) ? $nam=$nam[1] : "";
$cl["device"][$i]["type"]=$ty=getClientType($dev);
unset($udevinfo);
exec("udevadm info /sys/class/net/$dev 2> /dev/null", $udevinfo);
exec("udevadm info /sys/class/net/".escapeshellarg($dev)." 2> /dev/null", $udevinfo);
if ($nam == "ppp" && isset($devtty)) {
exec("udevadm info --name='$devtty' 2> /dev/null", $udevinfo);
exec("udevadm info --name=".escapeshellarg($devtty)." 2> /dev/null", $udevinfo);
}
if (!empty($udevinfo) && is_array($udevinfo)) {
$model = preg_only_match("/ID_MODEL_ENC=(.*)$/", $udevinfo);
Expand All @@ -49,16 +49,16 @@ function getClients($simple=true)
$cl["device"][$i]["vid"] = $vendorid;
$cl["device"][$i]["pid"] = $productid;
unset($mac);
exec("cat /sys/class/net/$dev/address 2> /dev/null", $mac);
exec("cat /sys/class/net/".escapeshellarg($dev)."/address 2> /dev/null", $mac);
$cl["device"][$i]["mac"] = empty($mac) ? "":$mac[0];
unset($ip);
exec("ifconfig $dev 2> /dev/null", $ip);
exec("ifconfig ".escapeshellarg($dev)." 2> /dev/null", $ip);
$cl["device"][$i]["ipaddress"] = preg_only_match("/.*inet ([0-9\.]+) .*/", $ip);

switch($ty) {
case "eth":
unset($res);
exec("ip link show $dev 2> /dev/null | grep -oP ' UP '", $res);
exec("ip link show ".escapeshellarg($dev)." 2> /dev/null | grep -oP ' UP '", $res);
if (empty($res) && empty($ipadd)) {
$cl["device"][$i]["connected"] = "n";
} else {
Expand All @@ -67,10 +67,10 @@ function getClients($simple=true)
break;
case "wlan":
unset($retiw);
exec("iwconfig $dev 2> /dev/null | sed -rn 's/.*(mode:master).*/1/ip'", $retiw);
exec("iwconfig ".escapeshellarg($dev)." 2> /dev/null | sed -rn 's/.*(mode:master).*/1/ip'", $retiw);
$cl["device"][$i]["isAP"] = !empty($retiw);
unset($retiw);
exec("iw dev $dev link 2> /dev/null", $retiw);
exec("iw dev ".escapeshellarg($dev)." link 2> /dev/null", $retiw);
if (!$simple && !empty($ssid=preg_only_match("/.*SSID:\s*([^\"]*).*/", $retiw)) ) {
$cl["device"][$i]["connected"] = "y";
$cl["device"][$i]["ssid"] = $ssid;
Expand Down Expand Up @@ -98,7 +98,7 @@ function getClients($simple=true)
break;
case "ppp":
unset($res);
exec("ip link show $dev 2> /dev/null | grep -oP '( UP | UNKNOWN)'", $res);
exec("ip link show ".escapeshellarg($dev)." 2> /dev/null | grep -oP '( UP | UNKNOWN)'", $res);
if ($simple) {
if (empty($res)) {
$cl["device"][$i]["connected"] = "n";
Expand Down Expand Up @@ -134,8 +134,8 @@ function getClients($simple=true)
getMobileLogin($pin,$pw,$user);
$opts=$pin.' '.$user.' '.$pw;
unset($res);
// exec("ip link show $dev 2> /dev/null | grep -oP ' UP '",$res);
exec("ifconfig -a | grep -i $dev -A 1 | grep -oP '(?<=inet )([0-9]{1,3}\.){3}'", $apiadd);
// exec("ip link show ".escapeshellarg($dev)." 2> /dev/null | grep -oP ' UP '",$res);
exec("ifconfig -a | grep -i ".escapeshellarg($dev)." -A 1 | grep -oP '(?<=inet )([0-9]{1,3}\.){3}'", $apiadd);
$apiadd = !empty($apiadd) ? $apiadd[0]."1" : "";
unset($res);
exec("$path/info_huawei.sh mode hilink $apiadd \"$opts\" ", $res);
Expand Down Expand Up @@ -181,7 +181,7 @@ function getClients($simple=true)
function getClientType($dev) {
loadClientConfig();
// check if device type stored in DEVTYPE or raspapType (from UDEV rule) protperty of the device
exec("udevadm info /sys/class/net/$dev 2> /dev/null", $udevadm);
exec("udevadm info /sys/class/net/".escapeshellarg($dev)." 2> /dev/null", $udevadm);
$type="none";
if (!empty($udevadm)) {
$type=preg_only_match("/raspapType=(\w*)/i",$udevadm);
Expand Down Expand Up @@ -254,7 +254,7 @@ function findCurrentClientIndex($clients)
function waitClientConnected($dev, $timeout=10)
{
do {
exec('ifconfig -a | grep -i '.$dev.' -A 1 | grep -oP "(?<=inet )([0-9]{1,3}\.){3}[0-9]{1,3}"', $res);
exec('ifconfig -a | grep -i '.escapeshellarg($dev).' -A 1 | grep -oP "(?<=inet )([0-9]{1,3}\.){3}[0-9]{1,3}"', $res);
$connected= !empty($res);
if (!$connected) {
sleep(1);
Expand All @@ -268,17 +268,17 @@ function setClientState($state)
$clients=getClients();
if (($idx = findCurrentClientIndex($clients)) >= 0) {
$dev = $clients["device"][$idx];
exec('ifconfig -a | grep -i '.$dev["name"].' -A 1 | grep -oP "(?<=inet )([0-9]{1,3}\.){3}[0-9]{1,3}"', $res);
exec('ifconfig -a | grep -i '.escapeshellarg($dev["name"]).' -A 1 | grep -oP "(?<=inet )([0-9]{1,3}\.){3}[0-9]{1,3}"', $res);
if (!empty($res)) {
$connected=$res[0];
}
switch($dev["type"]) {
case "wlan":
if ($state =="up") {
exec('sudo ip link set '.$dev["name"].' up');
exec('sudo ip link set '.escapeshellarg($dev["name"]).' up');
}
if (!empty($connected) && $state =="down") {
exec('sudo ip link set '.$dev["name"].' down');
exec('sudo ip link set '.escapeshellarg($dev["name"]).' down');
}
break;
case "hilink":
Expand All @@ -287,14 +287,14 @@ function setClientState($state)
$mode = ($state == "up") ? 1 : 0;
$pin=$user=$pw="";
getMobileLogin($pin,$pw,$user);
exec('sudo '.RASPI_CLIENT_SCRIPT_PATH.'/onoff_huawei_hilink.sh -c '.$mode.' -h '.$ipadd.' '.$pin.' '.$user.' '.$pw);
exec('sudo '.RASPI_CLIENT_SCRIPT_PATH.'/onoff_huawei_hilink.sh -c '.escapeshellarg($mode).' -h '.escapeshellarg($ipadd).' '.escapeshellarg($pin).' '.escapeshellarg($user).' '.escapeshellarg($pw));
break;
case "ppp":
if ($state == "up") {
exec('sudo ifup '.$dev["name"]);
exec('sudo ifup '.escapeshellarg($dev["name"]));
}
if (!empty($connected) && $state == "down") {
exec('sudo ifdown '.$dev["name"]);
exec('sudo ifdown '.escapeshellarg($dev["name"]));
}
break;
default:
Expand Down
24 changes: 17 additions & 7 deletions includes/hostapd.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ function DisplayHostAPDConfig()
// systemctl expects a unit name like [email protected], no extra quotes
$iface_nonescaped = $_POST['interface'];
if (preg_match('/^[a-zA-Z0-9_-]+$/', $iface_nonescaped)) { // validate interface name
exec('sudo '.RASPI_CONFIG.'/hostapd/servicestart.sh --interface ' .$iface_nonescaped. ' --seconds 1', $return);
$command = 'sudo '.RASPI_CONFIG.'/hostapd/servicestart.sh --interface ' . escapeshellarg($iface_nonescaped) . ' --seconds 1';
exec($command, $return);
} else {
throw new \Exception('Invalid network interface');
}
Expand Down Expand Up @@ -121,11 +122,13 @@ function DisplayHostAPDConfig()
if ($_POST['txpower'] != 'auto') {
$txpower = intval($_POST['txpower']);
$sdBm = $txpower * 100;
exec('sudo /sbin/iw dev '.$interface.' set txpower fixed '.$sdBm, $return);
$command = 'sudo /sbin/iw dev ' . $interface . ' set txpower fixed ' . escapeshellarg($sdBm);
exec($command, $return);
$status->addMessage('Setting transmit power to '.$_POST['txpower'].' dBm.', 'success');
$txpower = $_POST['txpower'];
} elseif ($_POST['txpower'] == 'auto') {
exec('sudo /sbin/iw dev '.$interface.' set txpower auto', $return);
$command = 'sudo /sbin/iw dev ' . $interface . ' set txpower auto';
exec($command, $return);
$status->addMessage('Setting transmit power to '.$_POST['txpower'].'.', 'success');
$txpower = $_POST['txpower'];
}
Expand Down Expand Up @@ -310,7 +313,7 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $reg_dom
$status->addMessage('Unknown interface '.htmlspecialchars($_POST['interface'], ENT_QUOTES), 'danger');
$good_input = false;
}
if (strlen($_POST['country_code']) !== 0 && strlen($_POST['country_code']) != 2) {
if (strlen($_POST['country_code']) !== 0 && !preg_match('/^[A-Z]{2}$/', $_POST['country_code'])) {
$status->addMessage('Country code must be blank or two characters', 'danger');
$good_input = false;
} else {
Expand All @@ -330,6 +333,7 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $reg_dom
$_POST['max_num_sta'] = $_POST['max_num_sta'] < 1 ? null : $_POST['max_num_sta'];

if ($good_input) {
$interface = escapeshellarg($_POST['interface']);
$return = updateHostapdConfig($ignore_broadcast_ssid,$wifiAPEnable,$bridgedEnable);

if (trim($country_code) != trim($reg_domain)) {
Expand Down Expand Up @@ -357,7 +361,9 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $reg_dom
scanConfigDir('/etc/dnsmasq.d/','uap0',$status);
$config = join(PHP_EOL, $config);
file_put_contents("/tmp/dnsmasqdata", $config);
system('sudo cp /tmp/dnsmasqdata '.RASPI_DNSMASQ_PREFIX.$ap_iface.'.conf', $return);
$destination = RASPI_DNSMASQ_PREFIX . escapeshellarg($ap_iface . '.conf');
$command = sprintf('sudo cp /tmp/dnsmasqdata %s', $destination);
system($command, $return);
} elseif ($bridgedEnable !==1) {
$dhcp_range = ($syscfg['dhcp-range'] =='') ? getDefaultNetValue('dnsmasq',$ap_iface,'dhcp-range') : $syscfg['dhcp-range'];
$config = [ '# RaspAP '.$_POST['interface'].' configuration' ];
Expand All @@ -370,7 +376,9 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $reg_dom
$config[] = PHP_EOL;
$config = join(PHP_EOL, $config);
file_put_contents("/tmp/dnsmasqdata", $config);
system('sudo cp /tmp/dnsmasqdata '.RASPI_DNSMASQ_PREFIX.$ap_iface.'.conf', $return);
$destination = RASPI_DNSMASQ_PREFIX . escapeshellarg($ap_iface . '.conf');
$command = sprintf('sudo cp /tmp/dnsmasqdata %s', $destination);
system($command, $return);
}

// Set dhcp values from system config, fallback to default if undefined
Expand Down Expand Up @@ -524,7 +532,9 @@ function updateHostapdConfig($ignore_broadcast_ssid,$wifiAPEnable,$bridgedEnable
$config.= parseUserHostapdCfg();

file_put_contents("/tmp/hostapddata", $config);
system("sudo cp /tmp/hostapddata " . RASPI_HOSTAPD_CONFIG, $result);
$destination = escapeshellarg(RASPI_HOSTAPD_CONFIG);
$command = sprintf("sudo cp /tmp/hostapddata %s", $destination);
system($command, $result);
return $result;
}

Expand Down
20 changes: 10 additions & 10 deletions includes/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function DisplayProviderConfig()
if ($id = 4) { // AdGuard requires country argument on connect
$arg = escapeshellarg(trim($_POST['country']));
}
exec("sudo $binPath $cmd $arg", $return);
exec("sudo ".escapeshellarg($binPath)." ".escapeshellarg($cmd)." ".escapeshellarg($arg), $return);
$return = stripArtifacts($return);
foreach ($return as $line) {
if (strlen(trim($line)) > 0) {
Expand All @@ -50,7 +50,7 @@ function DisplayProviderConfig()
} elseif (isset($_POST['StopProviderVPN'])) {
$status->addMessage('Attempting to disconnect VPN provider', 'info');
$cmd = getCliOverride($id, 'cmd_overrides', 'disconnect');
exec("sudo $binPath $cmd", $return);
exec("sudo ".escapeshellarg($binPath)." ".escapeshellarg($cmd), $return);
$return = stripArtifacts($return);
foreach ($return as $line) {
if (strlen(trim($line)) > 0) {
Expand Down Expand Up @@ -120,10 +120,10 @@ function saveProviderConfig($status, $binPath, $country, $id = null)
$cmd = getCliOverride($id, 'cmd_overrides', 'connect');
// mullvad requires relay set location before connect
if ($id == 2) {
exec("sudo $binPath relay set location $country", $return);
exec("sudo $binPath $cmd", $return);
exec("sudo ".escapeshellarg($binPath)." relay set location ".escapeshellarg($country), $return);
exec("sudo ".escapeshellarg($binPath)." ".escapeshellarg($cmd), $return);
} else {
exec("sudo $binPath $cmd $country", $return);
exec("sudo ".escapeshellarg($binPath)." ".escapeshellarg($cmd)." ".escapeshellarg($country), $return);
}
$return = stripArtifacts($return);
foreach ($return as $line) {
Expand Down Expand Up @@ -209,7 +209,7 @@ function getProviderStatus($id, $binPath)
{
$cmd = getCliOverride($id, 'cmd_overrides', 'status');
$pattern = getCliOverride($id, 'regex', 'status');
exec("sudo $binPath $cmd", $cmd_raw);
exec("sudo ".escapeshellarg($binPath)." ".escapeshellarg($cmd), $cmd_raw);
$cmd_raw = strtolower(($cmd_raw[0]));
if (!empty($cmd_raw[0])) {
if (preg_match($pattern, $cmd_raw, $match)) {
Expand All @@ -236,7 +236,7 @@ function getCountries($id, $binPath)
$cmd = getCliOverride($id, 'cmd_overrides', 'countries');
$pattern = getCliOverride($id, 'regex', 'pattern');
$replace = getCliOverride($id, 'regex', 'replace');
exec("sudo $binPath $cmd", $output);
exec("sudo ".escapeshellarg($binPath)." ".escapeshellarg($cmd), $output);

// CLI country output differs considerably between different providers.
// Ideally, custom parsing would be avoided in favor of a pure regex solution
Expand Down Expand Up @@ -336,7 +336,7 @@ function getProviderLog($id, $binPath, &$country)
{
$providerLog = '';
$cmd = getCliOverride($id, 'cmd_overrides', 'log');
exec("sudo $binPath $cmd", $cmd_raw);
exec("sudo ".escapeshellarg($binPath)." ".escapeshellarg($cmd), $cmd_raw);
$output = stripAnsiSequence($cmd_raw);
foreach ($output as $item) {
if (preg_match('/Country: (\w+)/', $item, $match)) {
Expand All @@ -357,7 +357,7 @@ function getProviderLog($id, $binPath, &$country)
function getProviderVersion($id, $binPath)
{
$cmd = getCliOverride($id, 'cmd_overrides', 'version');
$version = shell_exec("sudo $binPath $cmd");
$version = shell_exec("sudo ".escapeshellarg($binPath)." ".escapeshellarg($cmd));
$version = preg_replace('/^[^\w]+\s*/', '', $version);
return $version;
}
Expand All @@ -373,7 +373,7 @@ function getProviderVersion($id, $binPath)
function getAccountInfo($id, $binPath, $providerName)
{
$cmd = getCliOverride($id, 'cmd_overrides', 'account');
exec("sudo $binPath $cmd", $acct);
exec("sudo ".escapeshellarg($binPath)." ".escapeshellarg($cmd), $acct);
$acct = stripAnsiSequence($acct);
foreach ($acct as &$item) {
$item = preg_replace('/^[^\w]+\s*/', '', $item);
Expand Down
Loading