CVE-2026-9757: GEO my WP SQL Injection via Raw Query String Parameters
A SQL injection vulnerability has been discovered in the GEO my WP plugin for WordPress, tracked as CVE-2026-9757 with a CVSS v3.1 score of 7.5 (High). Affecting all plugin versions up to and including 4.5.5, this flaw is notable because it specifically circumvents WordPress's built-in input sanitization by reading attacker-controlled data directly from $_SERVER['QUERY_STRING'] via parse_str() — a vector that bypasses the wp_magic_quotes() protection applied to $_GET, $_POST, and $_COOKIE.
Vulnerability Overview
| Attribute | Value |
|---|---|
| CVE ID | CVE-2026-9757 |
| CVSS Score | 7.5 (High) |
| Affected Plugin | GEO my WP |
| Affected Versions | All versions up to and including 4.5.5 |
| Vulnerable Parameters | swlatlng, nelatlng |
| Bypass Mechanism | parse_str($_SERVER['QUERY_STRING']) skips wp_magic_quotes() |
| Authentication Required | None |
| Exploitation | Remote database access, data extraction |
About GEO my WP
GEO my WP is a WordPress plugin that adds geolocation and mapping features to WordPress sites, allowing content such as posts, users, and custom post types to be associated with geographic coordinates and displayed on interactive maps. The swlatlng and nelatlng parameters (southwest and northeast lat/lng bounding box coordinates) are used to filter map content by geographic area — and it is these parameters that are vulnerable to injection.
The Bypass Mechanism
WordPress applies wp_magic_quotes() at bootstrap time, which adds slashes to incoming data in $_GET, $_POST, $_COOKIE, and $_SERVER['REQUEST_URI']. This is a legacy defense that prevents basic SQL injection by escaping single quotes. However, wp_magic_quotes() does not process $_SERVER['QUERY_STRING'].
The GEO my WP plugin reads the vulnerable parameters using the following pattern:
parse_str($_SERVER['QUERY_STRING'], $params);
$swlatlng = $params['swlatlng'];
// $swlatlng is then used in an unparameterized SQL queryBecause $_SERVER['QUERY_STRING'] is read directly — before WordPress's magic quotes processing can apply — an attacker can submit a swlatlng or nelatlng value containing unescaped SQL syntax that is passed directly to the database query.
Exploitation
An unauthenticated attacker can exploit this vulnerability by sending a crafted HTTP GET request:
GET /wp-ajax.php?action=gmw_pt3_get_posts&swlatlng=1,1' UNION SELECT 1,user_login,user_pass,4,5,6 FROM wp_users--&nelatlng=2,2
HTTP/1.1 200 OK
[JSON response containing WordPress user credentials]Depending on the database user's privileges and the specific injection context, an attacker could:
- Extract all WordPress user credentials (usernames and password hashes) from
wp_users - Read arbitrary database tables including site options, post content, and custom data
- Enumerate the database schema to identify additional tables of interest
- Write files to the filesystem if the MySQL user has
FILEprivileges (uncommon but possible in misconfigured environments)
Because no authentication is required, the attack can be fully automated and executed against any publicly accessible WordPress site running an affected version of GEO my WP.
Affected Versions
All GEO my WP versions up to and including 4.5.5 are vulnerable. Sites that have not updated beyond this version should treat the vulnerability as critical given the unauthenticated nature of the attack.
Remediation
Update the Plugin
Update GEO my WP to the patched version via the WordPress admin panel or WP-CLI:
# Update via WP-CLI
wp plugin update geo-my-wp
# Verify installed version
wp plugin get geo-my-wp --field=versionCode-Level Fix Pattern
The correct remediation is to use prepared statements and avoid reading geolocation parameters from the raw query string:
// Vulnerable: reads from raw QUERY_STRING
parse_str($_SERVER['QUERY_STRING'], $params);
$lat = $params['swlatlng'];
// Secure: use sanitize_text_field on proper superglobal, then prepare query
$lat = sanitize_text_field($_GET['swlatlng'] ?? '');
// Use parameterized query
$results = $wpdb->get_results(
$wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ST_Within(coordinates, ST_MakeEnvelope(%f, %f, %f, %f, 4326))",
$sw_lat, $sw_lng, $ne_lat, $ne_lng)
);Additional Hardening
- Enable WAF rules targeting SQL injection patterns in URL query strings
- Implement a database activity monitor to detect unusual SELECT queries against sensitive tables (
wp_users,wp_options) - Apply principle of least privilege to the WordPress database user — revoke FILE and other non-essential privileges
- Consider restricting geolocation AJAX endpoints to authenticated users if the use case allows
Detection
Identify potential exploitation attempts in access logs:
# Look for SQL injection patterns in GEO my WP AJAX requests
grep "gmw_pt3_get_posts\|geo-my-wp" /var/log/nginx/access.log | \
grep -iE "(union|select|from|where|--|\%27|%23)"
# Check for unusual data dumps from the database layer
grep -i "wp_users\|user_pass\|INFORMATION_SCHEMA" /var/log/mysql/general.logImpact Assessment
| Impact Area | Description |
|---|---|
| Data Extraction | All database contents accessible to unauthenticated attackers |
| Credential Theft | WordPress user hashes exposed, enabling offline cracking |
| No Authentication Barrier | Any internet user can attempt exploitation |
| Geolocation Exposure | Location data associated with users and posts may be extracted |
| Lateral Movement | Stolen admin credentials enable full site takeover |
Key Takeaways
- CVE-2026-9757 affects GEO my WP versions up to 4.5.5 and allows unauthenticated SQL injection
- The vulnerability bypasses WordPress's
wp_magic_quotes()defense by reading parameters viaparse_str($_SERVER['QUERY_STRING']) - Exploitation requires no authentication and can be done with a single HTTP request
- Immediate action: update GEO my WP beyond version 4.5.5; apply WAF rules targeting SQLi patterns in geolocation requests
- This vulnerability class —
$_SERVER['QUERY_STRING']misuse — is a recurring issue in WordPress plugins that developers and auditors should specifically look for