JoomCCK Unauthenticated SQL Injection via `tags.save` (CVE-2026-49048)
by Kamil Soltanov (KARA-git) · 2026-07-05
- Severity
- Critical
- CVE
- CVE-2026-49048 (Advisory ID JOOMCCK-2026-001)
- Category
- web
- Affected product
- JoomCCK (com_joomcck) — Content Construction Kit extension for Joomla, by JoomCoder
- Affected versions
- 6.4.0 (latest at time of discovery; earlier 6.x presumed affected); no fixed version at time of writing
- Disclosed
- 2026-07-05
- Patch status
- unpatched
Tags
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-07 |
| Author / Researcher | Kamil Soltanov (KARA-git) |
| CVE / Advisory | CVE-2026-49048 (Advisory ID JOOMCCK-2026-001) |
| Category | web |
| Severity | Critical |
| CVSS Score | 8.7 (CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| Status | PoC |
| Tags | joomla, joomcck, com_joomcck, sql-injection, cwe-89, missing-authorization, cwe-862, unauthenticated, blind-sqli, union-based |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | JoomCCK (com_joomcck) — Content Construction Kit extension for Joomla, by JoomCoder |
| Versions Affected | 6.4.0 (latest at time of discovery; earlier 6.x presumed affected); no fixed version at time of writing |
| Language / Platform | PHP / Joomla CMS 4/5/6 |
| Authentication Required | No |
| Network Access Required | Yes |
Summary
JoomCCK’s custom MVC dispatcher (MControllerBase::execute()) invokes controller tasks without any CSRF token check or ACL/authorization check — its authorise() method is a no-op that always returns true. This makes the tags.save task, whose model method _saveTag() concatenates the user-supplied tag parameter directly into raw SQL (both a SELECT and an UPDATE statement) without escaping, reachable by a completely unauthenticated remote attacker. Joomla’s STRING input filter strips HTML but does not strip double quotes, which are the string delimiter used in the vulnerable query, allowing straightforward quote-breakout SQL injection (both UNION-based and time-based blind). The repository includes a PHP PoC (poc/poc.php) that loads the genuine Joomla Input/filter framework classes and runs the exact _saveTag() query against a live MariaDB instance to demonstrate quote breakout, UNION exfiltration of user password hashes, and time-based blind injection, along with a captured evidence transcript and a disclosure timeline showing the finding was reported to and acknowledged by the Joomla Security Strike Team.
Vulnerability Details
Root Cause
- Missing authorization (CWE-862) —
libraries/mint/mvc/controller/base.php,MControllerBase::execute()dispatches to task methods ($this->$doTask()) with nocheckToken()orauthorise()gate;authorise()unconditionally returnstrue. The component entry point (components/com_joomcck/joomcck.php) callsexecute(input->get('task'))directly, so every public controller task — including state-changing ones — is reachable without authentication. - SQL injection (CWE-89) —
components/com_joomcck/models/tags.php,_saveTag():Because1 2 3 4$tag = $app->input->getString('tag'); // Joomla STRING filter strips HTML but not " $query = ' SELECT a.* FROM #__js_res_tags AS a WHERE a.tag = "' . $tag . '"'; // injectable ... $query = 'UPDATE #__js_res_tags SET tag = "' . $tag . '" WHERE id =' . $id; // injectable"passes throughgetString()unmodified and is also the query’s string delimiter, an attacker can break out of the literal and append arbitrary SQL.
Attack Vector
- Attacker sends an unauthenticated GET/POST request to
index.php?option=com_joomcck&task=tags.savewith a craftedtagparameter, e.g.zzz" OR "1"="1orzzz" UNION SELECT id,username,password FROM #__users-- -. - The custom dispatcher executes
tags.savewith no login/token/ACL check. _saveTag()builds a SQL string by directly concatenating the unescapedtagvalue.- The injected SQL executes against the Joomla database — confirmed via UNION-based data exfiltration and
SLEEP()-based time delays in the author’s lab.
Impact
An unauthenticated remote attacker can read arbitrary data from the Joomla database (including #__users password hashes, session tokens, and other PII), modify rows in #__js_res_tags via the injectable UPDATE, and potentially chain with other unauthenticated tasks exposed by the same dispatcher flaw (tags.delete, records.copy, and several ajax.* enumeration endpoints), leading to full administrative takeover of the Joomla site.
Environment / Lab Setup
Target: Joomla CMS running JoomCCK (com_joomcck) 6.4.0, MariaDB backend (author's lab: MariaDB 11.8)
Attacker: Standard HTTP client (curl/browser) for remote exploitation; PHP CLI + genuine Joomla Input/Filter/String
framework packages for the local lab-reproduction PoC in poc/poc.php
Proof of Concept
PoC Script
See
poc/poc.php(local lab reproduction using real Joomla framework code) andpoc/poc-evidence.txt(captured run transcript) in this folder. Seedisclosure/timeline.mdfor the full coordinated-disclosure timeline.
| |
The remote curl commands target the live, unauthenticated tags.save task directly. The local poc.php script instantiates the real Joomla\Input\Input class to reproduce $app->input->getString('tag') exactly as JoomCCK calls it, then runs the verbatim _saveTag() SELECT query against a live database for four cases (benign, quote-breakout, UNION exfiltration, time-based blind), printing the filtered input, the resulting SQL, and the query results/timing for each — as captured in poc/poc-evidence.txt.
Detection & Indicators of Compromise
grep -E 'task=tags\.save.*tag=.*(%22|SLEEP|UNION|--)' /var/log/apache2/access.log
grep -E 'task=tags\.save.*tag=.*(%22|SLEEP|UNION|--)' /var/log/nginx/access.log
Signs of compromise:
- Requests to
index.php?option=com_joomcck&task=tags.save(ortags.delete,records.copy) with no valid session/login, especially containing",UNION,SLEEP(, or--in thetagparameter - MySQL/MariaDB errors referencing
#__js_res_tagsor column-count mismatches (error 1222) in the database or application logs - Unexplained multi-second response delays on
com_joomcckendpoints
Remediation
| Action | Detail |
|---|---|
| Primary fix | No vendor patch confirmed at time of writing; parameterize all com_joomcck queries using Joomla’s query builder ($db->quote()/$db->quoteName()) instead of string concatenation, and add Session::checkToken() + an authorise() ACL check to MControllerBase::execute() before all state-changing tasks |
| Interim mitigation | Disable or restrict access to com_joomcck front-end tasks via WAF rules blocking SQL metacharacters in the tag parameter, or take the component offline until patched |
References
Notes
Mirrored from https://github.com/KARA-git/CVE-2026-49048-JoomCCK-SQLi on 2026-07-05.