From 7ccc92a039175634f771a2362a6971fc1cb8404e Mon Sep 17 00:00:00 2001 From: Yuri Karamian Date: Mon, 22 Jun 2026 00:53:52 +0200 Subject: [PATCH] Harden VPSAG module: credential logging, path injection, suspension, signature, XSS - Redact decrypted reseller API credentials from module logs (ArkhostVPSAG_Error). - Validate client-controlled values before they enter upstream API URL paths (graph time, backup file, firewall rule id, ISO id, rDNS IP); restrict VPS ID to digits. Prevents path/parameter injection (IDOR). - Suspend via Disable/Enable instead of Stop/Start, and reject state-changing client-area actions on non-active services (suspended client can't power on). - Verify the provisioning callback signature with hash_equals instead of !=. - Fix callback assigned-IP assembly: keep all extra IPv4s, join with real newlines (was dropping the first IP and using a literal backslash-n). - Make callback html_entity_decode array-safe. - Escape untrusted output: JSON_HEX_TAG-encode serverInfo for the . + 'serverInfoJson' => json_encode($serverInfo, JSON_HEX_TAG | JSON_HEX_AMP) ?: '{}', 'operatingSystems' => $operatingSystems, 'token' => generate_token('plain'), '_LANG' => ArkhostVPSAG_Translation(), diff --git a/modules/servers/ArkhostVPSAG/callback.php b/modules/servers/ArkhostVPSAG/callback.php index 8e11dba..1036d8e 100644 --- a/modules/servers/ArkhostVPSAG/callback.php +++ b/modules/servers/ArkhostVPSAG/callback.php @@ -18,7 +18,9 @@ require_once ROOTDIR . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . ' use WHMCS\Database\Capsule; -$_POST = array_map('html_entity_decode', $_POST); +$_POST = array_map(function ($value) { + return is_string($value) ? html_entity_decode($value) : $value; +}, $_POST); // Look for the service by VPSAG ID in service properties $serviceProperty = Capsule::table('tblservice_properties') @@ -57,7 +59,7 @@ foreach ($_POST as $key => $value) { $rawSig .= hash('sha512', decrypt($server->password)); $signature = hash('sha256', $rawSig); -if ($_POST['sig'] != $signature) { +if (!hash_equals($signature, (string) ($_POST['sig'] ?? ''))) { http_response_code(403); exit('Invalid signature'); } @@ -79,15 +81,21 @@ $_POST['ips'] = array_map(function ($ip) { $mainIP = $_POST['mainip']; -$_POST['ips'] = array_filter($_POST['ips'], function ($ip) use ($mainIP) { - return $ip !== $mainIP; -}); +// Keep every additional IPv4 (exclude the primary IP and blanks), then append +// the IPv6 address. Stored newline-separated, as WHMCS expects. +$extraIps = array_values(array_filter($_POST['ips'], function ($ip) use ($mainIP) { + return $ip !== $mainIP && $ip !== ''; +})); + +if (!empty($_POST['ipv6'])) { + $extraIps[] = $_POST['ipv6']; +} Capsule::table('tblhosting')->where('id', $service->id)->update(array( 'username' => $_POST['username'], 'password' => encrypt($_POST['root']), 'dedicatedip' => $mainIP, - 'assignedips' => (!array_shift($_POST['ips']) ? $_POST['ipv6'] : implode('\n', $_POST['ips']) . '\n' . $_POST['ipv6']), + 'assignedips' => implode("\n", $extraIps), )); echo '*ok*'; diff --git a/modules/servers/ArkhostVPSAG/template/clientarea_direct.tpl b/modules/servers/ArkhostVPSAG/template/clientarea_direct.tpl index 6435e31..29b26bb 100644 --- a/modules/servers/ArkhostVPSAG/template/clientarea_direct.tpl +++ b/modules/servers/ArkhostVPSAG/template/clientarea_direct.tpl @@ -651,7 +651,7 @@ if (arkhostVNCHashDetected) {