diff --git a/dashboard/changes.txt b/dashboard/changes.txt index 5d18d53..8b43388 100755 --- a/dashboard/changes.txt +++ b/dashboard/changes.txt @@ -1,3 +1,99 @@ +xlx db v2.4.3 + +SECURITY UPDATE - All files updated to fix vulnerabilities + +This release addresses multiple security vulnerabilities including XSS (Cross-Site Scripting), +command injection, path traversal, and SSRF (Server-Side Request Forgery) attacks. + +Files Changed and Security Fixes: + +- "functions.php" + * Added sanitize_output() and sanitize_attribute() helper functions for XSS prevention + * Added validate_callsign(), validate_module(), validate_protocol() input validation functions + * Replaced exec() call in GetSystemUptime() with secure file reading from /proc/uptime + * Added input validation and shell argument escaping to VNStatGetData() + * Added array bounds checking to ParseTime() to prevent errors on malformed input + +- "class.interlink.php" + * Added input validation to SetName() - validates reflector name format + * Added input validation to SetAddress() - validates IP addresses and hostnames + * Added input validation to AddModule(), RemoveModule(), and HasModuleEnabled() + +- "class.node.php" + * Added input validation in constructor for all parameters + * IP addresses validated with filter_var() + * Protocol validated against whitelist + * Callsign format validated with regex + * LinkedModule validated as single A-Z letter + +- "class.parsexml.php" + * Added element name sanitization to prevent XML injection + * Added strip_tags() to remove HTML/XML from extracted content + +- "class.peer.php" + * Added input validation in constructor for all parameters + * Same validation as class.node.php for consistency + +- "class.reflector.php" + * Added path traversal prevention to SetXMLFile(), SetPIDFile(), and SetFlagFile() + * Added SSRF protection to CallHome() - blocks internal/private IP addresses + * Added validation to ReadInterlinkFile() to prevent path traversal + * Added XML entity encoding to PrepareInterlinkXML() and PrepareReflectorXML() + * Added URL validation to SetCallingHome() + * Added missing InterlinkCount(), GetInterlink(), and IsInterlinked() methods + +- "class.station.php" + * Added input validation in constructor for all parameters + * Callsign format validation + * Module validation + +- "config.inc.php" + * Secured external config file inclusion with path validation + * Added realpath() checks to prevent directory traversal + +- "modules.php" + * All output wrapped with sanitize_output() to prevent XSS + +- "peers.php" + * All peer data output sanitized with sanitize_output() and sanitize_attribute() + * URL and callsign outputs properly escaped + +- "reflectors.php" + * All XML element data sanitized before output + * Dashboard URLs and reflector names properly escaped + +- "repeaters.php" + * Added input validation for filter parameters + * All node/repeater data sanitized before output + * Flag images and URLs properly escaped + * IP addresses sanitized + +- "traffic.php" + * Added strict whitelist validation for interface parameter + * Interface names validated against configured list only + +- "users.php" + * Added input validation for filter parameters + * All station/user data sanitized before output + * Callsigns, suffixes, and module names properly escaped + +- "index.php" + * Added secure session configuration (HttpOnly, SameSite, Secure flags) + * Added security headers (X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy) + * Added whitelist validation for 'show' parameter + * Added validation for 'do' and 'callhome' parameters + * All configuration values sanitized before output to HTML + * JavaScript injection prevented in page refresh code + * All meta tags properly escaped + +Security Vulnerabilities Fixed: +- XSS (Cross-Site Scripting) - All user input and XML data now properly escaped +- Command Injection - Removed unsafe exec() calls, added shell argument escaping +- Path Traversal - File paths validated and restricted to expected directories +- SSRF (Server-Side Request Forgery) - CallHome validates URLs and blocks internal IPs +- Session Hijacking - Added HttpOnly, SameSite, and Secure cookie flags +- XML Injection - Element names sanitized, content stripped of tags + xlx db v2.4.1 you can now hide the liveircddb menu button, if you are running your db in https. diff --git a/dashboard/index.php b/dashboard/index.php index 19b8833..b8cc31c 100755 --- a/dashboard/index.php +++ b/dashboard/index.php @@ -1,9 +1,22 @@ SetFlagFile("./pgs/country.csv"); $Reflector->SetPIDFile($Service['PIDFile']); @@ -81,14 +115,14 @@ else {
- - - - - + + + + + -
- | Users / Modules | -Repeaters / Nodes (NodeCount(); ?>) | -Peers (PeerCount(); ?>) | +Repeaters / Nodes (NodeCount()); ?>) | +Peers (PeerCount()); ?>) | Modules list | Reflectors list | - your private hash in '.$CallingHome['HashFile'].' could not be created, please check your config file and the permissions for the defined folder. + your private hash in '.sanitize_output($CallingHome['HashFile']).' could not be created, please check your config file and the permissions for the defined folder. '; } } @@ -185,7 +219,7 @@ else { ?> - + diff --git a/dashboard/pgs/class.interlink.php b/dashboard/pgs/class.interlink.php index 296c196..eb6da90 100755 --- a/dashboard/pgs/class.interlink.php +++ b/dashboard/pgs/class.interlink.php @@ -12,34 +12,52 @@ class Interlink { $this->Modules = null; } - public function SetName($RefName) { $this->ReflectorName = trim($RefName); } - public function SetAddress($RefAdd) { $this->ReflectorAddress = trim($RefAdd); } + public function SetName($RefName) { + $RefName = trim($RefName); + // Validate reflector name format (XLX + 3 alphanumeric) + if (preg_match('/^[A-Z0-9]{3,10}$/i', $RefName)) { + $this->ReflectorName = strtoupper($RefName); + } + } + public function SetAddress($RefAdd) { + $RefAdd = trim($RefAdd); + // Validate it's a valid hostname or IP + if (filter_var($RefAdd, FILTER_VALIDATE_IP) || + filter_var($RefAdd, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) { + $this->ReflectorAddress = $RefAdd; + } + } public function GetName() { return $this->ReflectorName; } public function GetAddress() { return $this->ReflectorAddress; } public function GetModules() { return $this->Modules; } public function AddModule($Module) { - $Module = trim($Module); - if (strlen($Module) != 1) return false; - if (strpos($this->Modules, $Module) === false) { - $this->Modules .= $Module; - } - return true; + $Module = trim(strtoupper($Module)); + if (strlen($Module) != 1) return false; + if (!preg_match('/^[A-Z]$/', $Module)) return false; // Only A-Z + if (strpos($this->Modules, $Module) === false) { + $this->Modules .= $Module; + } + return true; } public function RemoveModule($Module) { - $Module = trim($Module); - if (strlen($Module) != 1) return false; - if (strpos($this->Modules, $Module) !== false) { - $this->Modules = substr($this->Modules, 0, strpos($this->Modules, $Module)-1).substr($this->Modules, strpos($this->Modules, $Module)+1, strlen($this->Modules)); - } - return true; + $Module = trim(strtoupper($Module)); + if (strlen($Module) != 1) return false; + if (!preg_match('/^[A-Z]$/', $Module)) return false; // Only A-Z + if (strpos($this->Modules, $Module) !== false) { + $this->Modules = str_replace($Module, '', $this->Modules); + } + return true; } public function HasModuleEnabled($Module) { - if (strlen($Module) != 1) return false; - return (strpos($this->Modules, $Module) !== false); + $Module = trim(strtoupper($Module)); + if (strlen($Module) != 1 || !preg_match('/^[A-Z]$/', $Module)) { + return false; + } + return (strpos($this->Modules, $Module) !== false); } } diff --git a/dashboard/pgs/class.node.php b/dashboard/pgs/class.node.php index e1076a5..6a0bf25 100755 --- a/dashboard/pgs/class.node.php +++ b/dashboard/pgs/class.node.php @@ -14,29 +14,44 @@ class Node { public function __construct($Callsign, $IP, $LinkedModule, $Protocol, $ConnectTime, $LastHeardTime, $RandomID) { - $this->IP = $IP; + // Validate and sanitize IP + $IP = trim($IP); + $this->IP = filter_var($IP, FILTER_VALIDATE_IP) ? $IP : '0.0.0.0'; - $this->Protocol = $Protocol; - $this->ConnectTime = ParseTime($ConnectTime); - $this->LastHeardTime = ParseTime($LastHeardTime); - - $this->FullCallsign = trim(str_replace(" ", "-", $Callsign)); - $this->FullCallsign = str_replace(" ", "-", $this->FullCallsign); - $this->FullCallsign = str_replace(" ", "-", $this->FullCallsign); - - if (strpos($Callsign, " ") !== false) { - $this->Callsign = trim(substr($Callsign, 0, strpos($Callsign, " "))); - $this->Suffix = trim(substr($Callsign, strpos($Callsign, " "), strlen($Callsign))); - $this->Prefix = strtoupper(trim(substr($Callsign, 0, 3))); - } - else { - $this->Callsign = trim($Callsign); - $this->Suffix = ""; - $this->Prefix = ""; - } + // Validate protocol + $Protocol = trim($Protocol); + $allowed_protocols = ['DPlus', 'DExtra', 'DCS', 'DMR', 'YSF', 'DEXTRA', 'DPLUS']; + $this->Protocol = in_array($Protocol, $allowed_protocols, true) ? $Protocol : 'Unknown'; + + $this->ConnectTime = ParseTime($ConnectTime); + $this->LastHeardTime = ParseTime($LastHeardTime); - $this->LinkedModule = trim($LinkedModule); - $this->RandomID = $RandomID; + // Sanitize callsign (remove excessive spaces, validate format) + $Callsign = trim(preg_replace('/\s+/', ' ', $Callsign)); + + $this->FullCallsign = str_replace(" ", "-", $Callsign); + + if (strpos($Callsign, " ") !== false) { + $this->Callsign = trim(substr($Callsign, 0, strpos($Callsign, " "))); + $this->Suffix = trim(substr($Callsign, strpos($Callsign, " "))); + $this->Prefix = strtoupper(trim(substr($Callsign, 0, 3))); + } + else { + $this->Callsign = trim($Callsign); + $this->Suffix = ""; + $this->Prefix = ""; + } + + // Validate callsign format (basic check) + if (!preg_match('/^[A-Z0-9]{1,10}$/i', $this->Callsign)) { + $this->Callsign = 'INVALID'; + } + + // Validate LinkedModule (single letter A-Z) + $LinkedModule = trim(strtoupper($LinkedModule)); + $this->LinkedModule = preg_match('/^[A-Z]$/', $LinkedModule) ? $LinkedModule : ''; + + $this->RandomID = $RandomID; } public function GetFullCallsign() { return $this->FullCallsign; } diff --git a/dashboard/pgs/class.parsexml.php b/dashboard/pgs/class.parsexml.php index 8a54b1f..dbd8451 100755 --- a/dashboard/pgs/class.parsexml.php +++ b/dashboard/pgs/class.parsexml.php @@ -7,21 +7,31 @@ class ParseXML { } public function GetElement($InputString, $ElementName) { - if (strpos($InputString, "<".$ElementName.">") === false) return false; - if (strpos($InputString, "".$ElementName.">") === false) return false; - - $Element = substr($InputString, strpos($InputString, "<".$ElementName.">")+strlen($ElementName)+2, strpos($InputString, "".$ElementName.">")-strpos($InputString, "<".$ElementName.">")-strlen($ElementName)-2); - return $Element; + // Sanitize element name to prevent XML injection + $ElementName = preg_replace('/[^a-zA-Z0-9_\-\s]/', '', $ElementName); + + if (strpos($InputString, "<".$ElementName.">") === false) return false; + if (strpos($InputString, "".$ElementName.">") === false) return false; + $Element = substr($InputString, strpos($InputString, "<".$ElementName.">")+strlen($ElementName)+2, strpos($InputString, "".$ElementName.">")-strpos($InputString, "<".$ElementName.">")-strlen($ElementName)-2); + + // Strip any remaining HTML/XML tags from the content + return strip_tags($Element); } public function GetAllElements($InputString, $ElementName) { - $Elements = array(); - while (strpos($InputString, $ElementName) !== false) { - $Elements[] = $this->GetElement($InputString, $ElementName); - $InputString = substr($InputString, strpos($InputString, "".$ElementName.">")+strlen($ElementName)+3, strlen($InputString)); - } - return $Elements; + // Sanitize element name to prevent XML injection + $ElementName = preg_replace('/[^a-zA-Z0-9_\-\s]/', '', $ElementName); + + $Elements = array(); + while (strpos($InputString, $ElementName) !== false) { + $element = $this->GetElement($InputString, $ElementName); + if ($element !== false) { + $Elements[] = $element; + } + $InputString = substr($InputString, strpos($InputString, "".$ElementName.">")+strlen($ElementName)+3, strlen($InputString)); + } + return $Elements; } } diff --git a/dashboard/pgs/class.peer.php b/dashboard/pgs/class.peer.php index ae39c1b..1ee1659 100755 --- a/dashboard/pgs/class.peer.php +++ b/dashboard/pgs/class.peer.php @@ -10,13 +10,30 @@ class Peer { private $LastHeardTime; public function __construct($Callsign, $IP, $LinkedModule, $Protocol, $ConnectTime, $LastHeardTime) { - - $this->IP = $IP; - $this->Protocol = $Protocol; - $this->ConnectTime = ParseTime($ConnectTime); - $this->LastHeardTime = ParseTime($LastHeardTime); - $this->Callsign = trim($Callsign); - $this->LinkedModule = trim($LinkedModule); + + // Validate and sanitize IP + $IP = trim($IP); + $this->IP = filter_var($IP, FILTER_VALIDATE_IP) ? $IP : '0.0.0.0'; + + // Validate protocol + $Protocol = trim($Protocol); + $allowed_protocols = ['DPlus', 'DExtra', 'DCS', 'DMR', 'YSF', 'DEXTRA', 'DPLUS']; + $this->Protocol = in_array($Protocol, $allowed_protocols, true) ? $Protocol : 'Unknown'; + + $this->ConnectTime = ParseTime($ConnectTime); + $this->LastHeardTime = ParseTime($LastHeardTime); + + // Sanitize and validate callsign + $Callsign = trim($Callsign); + if (preg_match('/^[A-Z0-9]{3,10}$/i', $Callsign)) { + $this->Callsign = strtoupper($Callsign); + } else { + $this->Callsign = 'INVALID'; + } + + // Validate LinkedModule (single letter A-Z) + $LinkedModule = trim(strtoupper($LinkedModule)); + $this->LinkedModule = preg_match('/^[A-Z]$/', $LinkedModule) ? $LinkedModule : ''; } diff --git a/dashboard/pgs/class.reflector.php b/dashboard/pgs/class.reflector.php index 099599c..cece0c8 100755 --- a/dashboard/pgs/class.reflector.php +++ b/dashboard/pgs/class.reflector.php @@ -37,50 +37,73 @@ class xReflector { } public function LoadXML() { - if ($this->XMLFile != null) { - $handle = fopen($this->XMLFile, 'r'); - $this->XMLContent = fread($handle, filesize($this->XMLFile)); - fclose($handle); + if ($this->XMLFile != null) { + $handle = fopen($this->XMLFile, 'r'); + $this->XMLContent = fread($handle, filesize($this->XMLFile)); + fclose($handle); - # XLX alphanumeric naming... - $this->ServiceName = substr($this->XMLContent, strpos($this->XMLContent, "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '. $module .' | -'. (empty($PageOptions['ModuleNames'][$module]) ? '-' : $PageOptions['ModuleNames'][$module]) .' | +'. sanitize_output($module) .' | +'. sanitize_output(empty($PageOptions['ModuleNames'][$module]) ? '-' : $PageOptions['ModuleNames'][$module]) .' | '. count($Reflector->GetNodesInModulesByID($module)) .' | -'. 'REF' . $ReflectorNumber . $module . 'L' .' | -'. (is_numeric($ReflectorNumber) ? '*' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .' | -'. 'XRF' . $ReflectorNumber . $module . 'L' .' | -'. (is_numeric($ReflectorNumber) ? 'B' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .' | -'. 'DCS' . $ReflectorNumber . $module . 'L' .' | -'. (is_numeric($ReflectorNumber) ? 'D' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .' | -'. (4000+$i) .' | -'. (9+$i) .' | +'. sanitize_output('REF' . $ReflectorNumber . $module . 'L') .' | +'. sanitize_output(is_numeric($ReflectorNumber) ? '*' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .' | +'. sanitize_output('XRF' . $ReflectorNumber . $module . 'L') .' | +'. sanitize_output(is_numeric($ReflectorNumber) ? 'B' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .' | +'. sanitize_output('DCS' . $ReflectorNumber . $module . 'L') .' | +'. sanitize_output(is_numeric($ReflectorNumber) ? 'D' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .' | +'. sanitize_output(4000+$i) .' | +'. sanitize_output(9+$i) .' | '.$Name.' | '; +'.sanitize_output($Name).' | '; } else { echo ' -'.$Name.' | '; +'.sanitize_output($Name).' | '; } echo ' -'.date("d.m.Y H:i", $Reflector->Peers[$i]->GetLastHeardTime()).' | -'.FormatSeconds(time()-$Reflector->Peers[$i]->GetConnectTime()).' s | -'.$Reflector->Peers[$i]->GetProtocol().' | -'.$Reflector->Peers[$i]->GetLinkedModule().' | '; +'.sanitize_output(date("d.m.Y H:i", $Reflector->Peers[$i]->GetLastHeardTime())).' | +'.sanitize_output(FormatSeconds(time()-$Reflector->Peers[$i]->GetConnectTime())).' s | +'.sanitize_output($Reflector->Peers[$i]->GetProtocol()).' | +'.sanitize_output($Reflector->Peers[$i]->GetLinkedModule()).' | '; if ($PageOptions['PeerPage']['IPModus'] != 'HideIP') { - echo ' -'; + echo ' + | '; $Bytes = explode(".", $Reflector->Peers[$i]->GetIP()); if ($Bytes !== false && count($Bytes) == 4) { switch ($PageOptions['PeerPage']['IPModus']) { - case 'ShowLast1ByteOfIP' : echo $PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$Bytes[3]; break; - case 'ShowLast2ByteOfIP' : echo $PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$Bytes[2].'.'.$Bytes[3]; break; - case 'ShowLast3ByteOfIP' : echo $PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$Bytes[1].'.'.$Bytes[2].'.'.$Bytes[3]; break; - default : echo $Reflector->Peers[$i]->GetIP(); + case 'ShowLast1ByteOfIP' : echo sanitize_output($PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$Bytes[3]); break; + case 'ShowLast2ByteOfIP' : echo sanitize_output($PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$Bytes[2].'.'.$Bytes[3]); break; + case 'ShowLast3ByteOfIP' : echo sanitize_output($PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$Bytes[1].'.'.$Bytes[2].'.'.$Bytes[3]); break; + default : echo sanitize_output($Reflector->Peers[$i]->GetIP()); } } echo ' | '; diff --git a/dashboard/pgs/reflectors.php b/dashboard/pgs/reflectors.php index d79ce5a..9c37a93 100755 --- a/dashboard/pgs/reflectors.php +++ b/dashboard/pgs/reflectors.php @@ -30,15 +30,15 @@ $odd = ""; for ($i=0;$i|||||||||||||||||||||||||||||||||||||||||||||||||
| '.($i+1).' | '.$NAME.' | diff --git a/dashboard/pgs/repeaters.php b/dashboard/pgs/repeaters.php index bdf8d6f..1af1829 100755 --- a/dashboard/pgs/repeaters.php +++ b/dashboard/pgs/repeaters.php @@ -1,15 +1,14 @@ '; @@ -87,14 +86,14 @@ if ($PageOptions['UserPage']['ShowFilter']) {@@ -161,19 +160,19 @@ for ($i=0;$i<$Reflector->NodeCount();$i++) { | ';
list ($Flag, $Name) = $Reflector->GetFlag($Reflector->Nodes[$i]->GetCallSign());
if (file_exists("./img/flags/".$Flag.".png")) {
- echo ' |
- Nodes[$i]->GetSuffix(); - echo '" class="pl" target="_blank">'.$Reflector->Nodes[$i]->GetCallSign(); - if ($Reflector->Nodes[$i]->GetSuffix() != "") { echo '-'.$Reflector->Nodes[$i]->GetSuffix(); } + | Nodes[$i]->GetSuffix()); + echo '" class="pl" target="_blank">'.sanitize_output($Reflector->Nodes[$i]->GetCallSign()); + if ($Reflector->Nodes[$i]->GetSuffix() != "") { echo '-'.sanitize_output($Reflector->Nodes[$i]->GetSuffix()); } echo ' | '; if (($Reflector->Nodes[$i]->GetPrefix() == 'REF') || ($Reflector->Nodes[$i]->GetPrefix() == 'XRF')) { switch ($Reflector->Nodes[$i]->GetPrefix()) { - case 'REF' : echo 'REF-Link'; break; - case 'XRF' : echo 'XRF-Link'; break; + case 'REF' : echo 'REF-Link'; break; + case 'XRF' : echo 'XRF-Link'; break; } } else { @@ -187,20 +186,20 @@ for ($i=0;$i<$Reflector->NodeCount();$i++) { } } echo ' | -'.date("d.m.Y H:i", $Reflector->Nodes[$i]->GetLastHeardTime()).' | -'.FormatSeconds(time()-$Reflector->Nodes[$i]->GetConnectTime()).' s | -'.$Reflector->Nodes[$i]->GetProtocol().' | -'.$Reflector->Nodes[$i]->GetLinkedModule().' | '; +'.sanitize_output(date("d.m.Y H:i", $Reflector->Nodes[$i]->GetLastHeardTime())).' | +'.sanitize_output(FormatSeconds(time()-$Reflector->Nodes[$i]->GetConnectTime())).' s | +'.sanitize_output($Reflector->Nodes[$i]->GetProtocol()).' | +'.sanitize_output($Reflector->Nodes[$i]->GetLinkedModule()).' | '; if ($PageOptions['RepeatersPage']['IPModus'] != 'HideIP') { echo ''; $Bytes = explode(".", $Reflector->Nodes[$i]->GetIP()); if ($Bytes !== false && count($Bytes) == 4) { switch ($PageOptions['RepeatersPage']['IPModus']) { - case 'ShowLast1ByteOfIP' : echo $PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[3]; break; - case 'ShowLast2ByteOfIP' : echo $PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[2].'.'.$Bytes[3]; break; - case 'ShowLast3ByteOfIP' : echo $PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[1].'.'.$Bytes[2].'.'.$Bytes[3]; break; - default : echo $Reflector->Nodes[$i]->GetIP(); + case 'ShowLast1ByteOfIP' : echo sanitize_output($PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[3]); break; + case 'ShowLast2ByteOfIP' : echo sanitize_output($PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[2].'.'.$Bytes[3]); break; + case 'ShowLast3ByteOfIP' : echo sanitize_output($PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[1].'.'.$Bytes[2].'.'.$Bytes[3]); break; + default : echo sanitize_output($Reflector->Nodes[$i]->GetIP()); } } echo ' | '; diff --git a/dashboard/pgs/traffic.php b/dashboard/pgs/traffic.php index 46f62e2..b60eaad 100644 --- a/dashboard/pgs/traffic.php +++ b/dashboard/pgs/traffic.php @@ -1,25 +1,26 @@ @@ -33,11 +34,11 @@ else {'.$VNStat['Interfaces'][$i]['Name'].'';
- if ($i < count($VNStat['Interfaces'])) {
- echo ' '; - } - } + echo ''.sanitize_output($VNStat['Interfaces'][$i]['Name']).''; + if ($i < count($VNStat['Interfaces'])-1) { + echo ' '; + } + } ?> |
|