Deep scan: duplicate curl, type bugs, and security hardening across service plugins #146
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Deep code scan found additional bugs and security improvements needed. These are the same class of issues as #139 (which fixed SendGrid, Reddit, TikTok, Pinterest) but in 3 more plugins, plus new findings.
Bugs (CRITICAL)
1. Duplicate curl_setopt_array + undefined
$token— 3 more pluginsSame pattern as #139 but in plugins that were missed:
plg_mokosuitecross_convertkit/src/Extension/ConvertkitService.php$tokenundefined (should be$apiSecret)plg_mokosuitecross_brevo/src/Extension/BrevoService.php$tokenundefined + wrong auth header (should beapi-key:notBearer)plg_mokosuitecross_constantcontact/src/Extension/ConstantcontactService.phpFix: Remove the second
curl_setopt_array()call in each plugin'spublish()method.2. Medium
getUserId()returns array instead of stringFile:
plg_mokosuitecross_medium/src/Extension/MediumService.php:166Method declares
return stringbut the error path returns['valid' => false, ...]— an array copy-pasted fromvalidateCredentials(). Will cause PHP type error.Fix: Change line 166 to
return '';3. Mailchimp incorrect HTTP status check
File:
plg_mokosuitecross_mailchimp/src/Extension/MailchimpService.php:98Mailchimp campaign creation returns
201 Created, not200. This means campaign creation always fails even with valid credentials.Fix: Change to
if ($httpCode < 200 || $httpCode >= 300 || empty($data['id']))Security Hardening (MEDIUM)
4. Exception details exposed in ServiceController
File:
com_mokosuitecross/src/Controller/ServiceController.php:95-100Full exception with stack trace exposed to client. Should catch and return generic error message.
5. DispatchController missing CSRF check
File:
com_mokosuitecross/src/Controller/DispatchController.php:47POST endpoint modifies database state without
$this->checkToken(). Note: This is a REST API endpoint — may intentionally skip CSRF for API consumers, but should be documented or use API token auth instead.6. SQL WHERE IN uses implode instead of whereIn()
Files:
DispatchController.php:112,CrossPostDispatcher.php:128,146,QueueProcessor.php:351-375All use
implode(',', $ids)in SQL WHERE IN clauses. Values are cast to int so not exploitable, but should use Joomla's$query->whereIn()for consistency.7. Bluesky MD5 cache key
File:
plg_mokosuitecross_bluesky/src/Extension/BlueskyService.php:130Uses
md5()for cache key generation. Not a security risk (just cache indexing) but should usehash('sha256', ...).Acceptance Criteria
curl_setopt_arrayremoved from ConvertKit, Brevo, Constant ContactgetUserId()returns''on error instead of array$httpCode >= 200 && $httpCode < 300whereIn()instead ofimplodehash('sha256', ...)instead ofmd5()Branch created:
feature/146-deep-scan-duplicate-curl-type-bugs-and-s