Leaving a skeleton key under the mat of a shop nobody visits
CVE-2026-3456 is an unauthenticated SQL injection in the GeekyBot WordPress plugin (versions ≤ 1.2.0) via the attributekey parameter. The flaw stems from missing parameterized queries — user input is concatenated directly into a SQL statement, letting any remote attacker append UNION SELECT or time-based blind payloads to exfiltrate the WordPress database contents, including wp_users hashes, WooCommerce customer PII, and session tokens. Affected versions are ≤ 1.2.0; the fix shipped in 1.2.1 (changeset 3474168). The current plugin version is 2.1.1.
The vendor CVSS of 7.5 HIGH is *mathematically correct* for the vector (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N) — unauthenticated, low-complexity, high confidentiality impact. But CVSS ignores installed base and blast radius. GeekyBot has roughly 6,000 active installations worldwide. For an enterprise managing 10,000 hosts, the probability of this plugin existing anywhere in the fleet is near zero. Even if it does, the impact is a single WooCommerce site's database — not a domain, not a fleet, not a supply chain. The vendor rating dramatically overstates the real-world risk to any enterprise SOC.
4 steps from start to impact.
Identify a WordPress site running GeekyBot ≤ 1.2.0
wp-content/plugins/geeky-bot). The plugin exposes AJAX endpoints registered via wp_ajax_nopriv_* hooks, which are enumerable without authentication.- Target site runs WordPress with GeekyBot plugin ≤ 1.2.0 active
- The AJAX endpoint is reachable over HTTP/HTTPS
- Only ~6,000 sites globally have this plugin installed — the target surface is minuscule
- Enterprise WordPress deployments rarely use niche WooCommerce chatbot plugins
- WAFs with WordPress-specific rulesets (Wordfence, Sucuri, Cloudflare WAF) block common SQLi payloads at the edge
Send crafted SQL injection payload via attributekey
attributekey parameter. Because the parameter is concatenated directly into the query without $wpdb->prepare(), both UNION-based and time-based blind injection are viable. Tools like sqlmap automate this trivially once the injection point is confirmed.- Network path to the WordPress site (public internet for most WP installs)
- No WAF or IPS blocking SQLi signatures in the request
- Modern WAFs (Cloudflare, Sucuri, Wordfence firewall module) catch canonical SQLi payloads
- WordPress sites behind CDNs may not expose raw AJAX endpoints directly
Exfiltrate database contents
--dump or manual UNION queries, the attacker extracts wp_users (usernames and phpass hashes), wp_options (site secrets, API keys), and WooCommerce tables (wp_wc_orders, wp_wc_customer_lookup) containing customer names, emails, addresses, and order history. The CVSS vector specifies C:H/I:N/A:N — this is a read-only exfiltration chain; the attacker cannot write to the database or achieve code execution through this vector alone.- Successful SQLi from step 2
- Database user has SELECT privileges on target tables (WordPress default: yes)
- WooCommerce stores using external payment gateways (Stripe, PayPal) do not store card numbers in the database
- Data exfiltration volume may be limited by query timeouts or response size limits
- If the site uses a separate, locked-down database user with restricted SELECT grants (rare), blast radius shrinks further
Crack admin hashes or pivot with stolen secrets
wp_users phpass hashes offline for cracking with hashcat (mode 400). Weak passwords fall quickly. Alternatively, stolen API keys or WordPress auth salts from wp_options can be used to forge session cookies. This is a *post-exfiltration* step that extends impact beyond confidentiality, but it is not part of the CVE itself.- Extracted password hashes or secret keys from step 3
- Weak admin passwords or reused credentials
- Strong, unique admin passwords resist offline cracking
- MFA on WordPress admin (via plugin) blocks credential reuse
- This step is outside the CVE scope — it requires additional attacker effort
plugin list, or your WordPress management platform) to confirm no instance of geeky-bot exists. If absent, close the ticket. This is a LOW-severity item with no mitigation SLA — treat as backlog hygiene.$wpdb->prepare() to the vulnerable query. As a LOW-severity finding, there is no noisgate mitigation SLA — go straight to the remediation window, which is best-effort backlog.admin-ajax.php requests. This blocks generic SQLi payloads and buys time even for unpatched instances. Residual risk drops because the injection vector is blocked at the application edge.- Network segmentation alone — the attack arrives over the same HTTPS port that serves legitimate traffic. Firewall rules cannot distinguish SQLi from normal AJAX requests without L7 inspection.
- WordPress auto-updates for plugins — while WordPress supports plugin auto-updates, many enterprises disable them for change control. Do not assume auto-update has patched this.
- PHP version upgrades — the vulnerability is in application-layer SQL construction, not a PHP runtime flaw. Upgrading PHP does not remediate.
The supporting signals.
| In-the-Wild Exploitation | No evidence. Not listed in CISA KEV. No campaigns attributed to this CVE. No GreyNoise tags observed. |
|---|---|
| Proof-of-Concept | None public. No PoC found on pocindex.io, GitHub, ExploitDB, or Nuclei templates as of 2026-09-27. The injection is trivial (unsanitized $_GET/$_POST into SQL), so a weaponized PoC could be written in minutes by anyone who reads the diff — but nobody has bothered. |
| EPSS | 0.00463 (0.463%) — bottom quartile. Exploitation probability over the next 30 days is very low. |
| KEV Status | Not listed. No CISA deadline applies. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N — Network-reachable, no auth, no user interaction, but impact is confidentiality-only. No integrity or availability damage. |
| Affected Versions | GeekyBot ≤ 1.2.0 (all prior versions). Plugin author: *ahmadgb*. |
| Fixed Version | 1.2.1 (changeset 3474168). Current release is 2.1.1. |
| Installed Base | ~6,000 active installations per wordpress.org. This is an extremely niche WooCommerce chatbot — vanishingly unlikely in enterprise fleets. |
| Researcher | Nguyen Ba Khanh, HPT Vietnam Corporation (per Patchstack advisory). CNA: Wordfence. |
| Disclosure Timeline | Reported 2026-01-28 → Published 2026-05-05 → Last modified 2026-06-17. Status: *Deferred* in NVD. |
Sources.
Why this verdict
- Microscopic installed base eliminates fleet relevance. ~6,000 sites worldwide run GeekyBot. For a 10,000-host enterprise, the probability of any host running this plugin rounds to zero. Even WordPress-heavy shops rarely deploy niche WooCommerce AI chatbots.
- Confidentiality-only impact with site-level blast radius. The CVSS vector explicitly marks I:N/A:N. The worst outcome is reading one WordPress database — customer PII and admin hashes. There is no path to code execution, lateral movement, or fleet compromise through this CVE alone.
- Role multiplier: no high-value-role overlap. GeekyBot is a WooCommerce storefront chatbot. It does not run on domain controllers, identity providers, hypervisors, CI/CD, backup infrastructure, network edge appliances, or any canonically high-value component. 100% of its installs occupy the low-value ecommerce tier. The blast radius is one site's database — not domain, not fleet, not supply chain. The HIGH floor does not apply because no plausible high-value-role deployment exists for this component.
- No exploitation signals. Zero in-the-wild exploitation, no KEV listing, no public PoC, EPSS in the bottom quartile at 0.46%. Nobody is attacking this.
- Vendor CVSS of 7.5 is mechanically correct but operationally misleading. The vector math is right for an unauth SQLi. But CVSS doesn't encode installed base, blast radius, or exploitation probability. For enterprise prioritization, this is backlog noise.
Why not higher?
The vulnerability *is* an unauthenticated SQL injection with zero friction at the network layer, which normally warrants concern. However, every severity-boosting factor is negated: the affected component has ~6,000 global installs (no enterprise footprint), impact is read-only (no RCE, no lateral movement), no PoC exists, no exploitation has been observed, and the component occupies zero high-value deployment roles. Promoting to MEDIUM would overstate the risk relative to every other item competing for the same patching window.
Why not lower?
Dropping to IGNORE would be inappropriate because the vulnerability is real, trivially exploitable if targeted, and affects a database that may contain customer PII subject to GDPR/PCI obligations. Any enterprise that *does* run this plugin should still patch. LOW correctly signals 'fix if present, don't hunt for it.'
Crowdsourced verification payload.
Run this script on each WordPress host (or via SSH from your auditor workstation) as any user with read access to the WordPress plugin directory. Example: bash check_geekybot.sh /var/www/html where the argument is the WordPress root. No elevated privileges required.
#!/usr/bin/env bash
# check_geekybot.sh — CVE-2026-3456 GeekyBot SQLi version checker
# Usage: bash check_geekybot.sh <wordpress_root>
# Exit codes: 0=PATCHED/not installed, 1=VULNERABLE, 2=UNKNOWN
set -euo pipefail
WP_ROOT="${1:?Usage: $0 <wordpress_root>}"
PLUGIN_DIR="$WP_ROOT/wp-content/plugins/geeky-bot"
MAIN_FILE="$PLUGIN_DIR/geeky-bot.php"
if [ ! -d "$PLUGIN_DIR" ]; then
echo "PATCHED — GeekyBot plugin is not installed at $WP_ROOT"
exit 0
fi
if [ ! -f "$MAIN_FILE" ]; then
echo "UNKNOWN — Plugin directory exists but main file not found"
exit 2
fi
# Extract version from plugin header
VERSION=$(grep -i '^[[:space:]]*\*[[:space:]]*Version:' "$MAIN_FILE" | head -1 | sed 's/.*Version:[[:space:]]*//' | tr -d '[:space:]')
if [ -z "$VERSION" ]; then
echo "UNKNOWN — Could not parse version from $MAIN_FILE"
exit 2
fi
echo "Detected GeekyBot version: $VERSION"
# Compare versions — vulnerable if <= 1.2.0
# Using sort -V for version comparison
FIXED="1.2.1"
OLDEST=$(printf '%s\n%s' "$VERSION" "$FIXED" | sort -V | head -1)
if [ "$OLDEST" = "$FIXED" ] || [ "$VERSION" = "$FIXED" ]; then
# VERSION >= FIXED
echo "PATCHED — GeekyBot $VERSION is >= $FIXED (CVE-2026-3456 fixed)"
exit 0
else
echo "VULNERABLE — GeekyBot $VERSION is below $FIXED (CVE-2026-3456 applies)"
exit 1
fi