From 6f7549fa7a82dd400f48f40d7812e2fe309b92a2 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 23 Jun 2026 10:50:34 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20address=20PR=20review=20findings=20?= =?UTF-8?q?=E2=80=94=20security,=20performance,=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - togglePlugin: restrict scope to mokosuiteclient plugins only (was any plugin) - DevTools: replace full-table hits reset on every request with config toggle - CurrentIpField: prefer REMOTE_ADDR over spoofable X-Forwarded-For - SQL: explicit (int) cast on $days interpolation in chart queries - Heartbeat: enable SSL peer verification (was disabled) - script.php: remove orphaned docblock --- .../src/Controller/DisplayController.php | 2 +- .../admin/src/Model/DashboardModel.php | 8 ++++-- .../src/Extension/DevTools.php | 17 ++--------- .../src/Field/CurrentIpField.php | 28 +++++++++++-------- source/script.php | 10 ------- 5 files changed, 25 insertions(+), 40 deletions(-) diff --git a/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php b/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php index a5d16acf..5aeb97f0 100644 --- a/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php +++ b/source/packages/com_mokosuiteclient/admin/src/Controller/DisplayController.php @@ -204,7 +204,7 @@ class DisplayController extends BaseController CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_FOLLOWLOCATION => true, - CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYPEER => true, ]); $response = curl_exec($ch); diff --git a/source/packages/com_mokosuiteclient/admin/src/Model/DashboardModel.php b/source/packages/com_mokosuiteclient/admin/src/Model/DashboardModel.php index 59647ecc..48c28a7d 100644 --- a/source/packages/com_mokosuiteclient/admin/src/Model/DashboardModel.php +++ b/source/packages/com_mokosuiteclient/admin/src/Model/DashboardModel.php @@ -277,7 +277,9 @@ class DashboardModel extends BaseDatabaseModel ->select([$db->quoteName('element'), $db->quoteName('protected')]) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('extension_id') . ' = ' . $extensionId) - ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')); + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where('(' . $db->quoteName('element') . ' = ' . $db->quote('mokosuiteclient') + . ' OR ' . $db->quoteName('element') . ' LIKE ' . $db->quote('mokosuiteclient\\_%') . ')'); $db->setQuery($query); $ext = $db->loadObject(); @@ -568,7 +570,7 @@ class DashboardModel extends BaseDatabaseModel $db->setQuery( "SELECT DATE(" . $db->quoteName('created') . ") AS day, COUNT(*) AS total" . " FROM " . $db->quoteName('#__mokosuiteclient_waf_log') - . " WHERE " . $db->quoteName('created') . " >= DATE_SUB(NOW(), INTERVAL $days DAY)" + . " WHERE " . $db->quoteName('created') . " >= DATE_SUB(NOW(), INTERVAL " . (int) $days . " DAY)" . " GROUP BY day ORDER BY day" ); $rows = $db->loadObjectList() ?: []; @@ -609,7 +611,7 @@ class DashboardModel extends BaseDatabaseModel "SELECT DATE(" . $db->quoteName('log_date') . ") AS day, COUNT(*) AS total" . " FROM " . $db->quoteName('#__action_logs') . " WHERE " . $db->quoteName('message_language_key') . " = 'PLG_ACTIONLOG_JOOMLA_USER_LOGGED_IN'" - . " AND " . $db->quoteName('log_date') . " >= DATE_SUB(NOW(), INTERVAL $days DAY)" + . " AND " . $db->quoteName('log_date') . " >= DATE_SUB(NOW(), INTERVAL " . (int) $days . " DAY)" . " GROUP BY day ORDER BY day" ); $rows = $db->loadObjectList() ?: []; diff --git a/source/packages/plg_system_mokosuiteclient_devtools/src/Extension/DevTools.php b/source/packages/plg_system_mokosuiteclient_devtools/src/Extension/DevTools.php index d92bfe78..46f00076 100644 --- a/source/packages/plg_system_mokosuiteclient_devtools/src/Extension/DevTools.php +++ b/source/packages/plg_system_mokosuiteclient_devtools/src/Extension/DevTools.php @@ -58,21 +58,8 @@ class DevTools extends CMSPlugin implements SubscriberInterface $config->set('offline', 1); } - // Suppress hit recording - try - { - $db = Factory::getDbo(); - $db->setQuery( - $db->getQuery(true) - ->update($db->quoteName('#__content')) - ->set($db->quoteName('hits') . ' = 0') - ->where($db->quoteName('hits') . ' > 0') - )->execute(); - } - catch (\Throwable $e) - { - // Silent - } + // Suppress hit recording by disabling the content hit counter + $config->set('record_hits', 0); } /** diff --git a/source/packages/plg_system_mokosuiteclient_firewall/src/Field/CurrentIpField.php b/source/packages/plg_system_mokosuiteclient_firewall/src/Field/CurrentIpField.php index 8c6870f6..956e2202 100644 --- a/source/packages/plg_system_mokosuiteclient_firewall/src/Field/CurrentIpField.php +++ b/source/packages/plg_system_mokosuiteclient_firewall/src/Field/CurrentIpField.php @@ -20,23 +20,29 @@ class CurrentIpField extends FormField protected function getInput(): string { - $ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? ''; + $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'; + $forwarded = ''; - if (!empty($ip)) + if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $ip = trim(explode(',', $ip)[0]); + $candidate = trim(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]); + if (filter_var($candidate, FILTER_VALIDATE_IP)) + { + $forwarded = $candidate; + } } - if (empty($ip)) - { - $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0'; - } - - return '
' + $html = '
' . '' . htmlspecialchars($ip) . '' - . '' - . '
'; + . ''; + + if ($forwarded && $forwarded !== $ip) + { + $html .= 'Proxy: ' . htmlspecialchars($forwarded) . ''; + } + + return $html . '
'; } } diff --git a/source/script.php b/source/script.php index fccb9ef9..f604699c 100644 --- a/source/script.php +++ b/source/script.php @@ -22,16 +22,6 @@ use Joomla\CMS\Log\Log; */ class Pkg_MokosuiteclientInstallerScript { - /** - * Runs after package installation/update. - * - * @param string $type Installation type - * @param InstallerAdapter $parent Parent installer - * - * @return void - * - * @since 2.2.0 - */ /** * Runs before package installation/update. *