“`json
{
“analysis”: “Atomic Edge analysis of CVE-2026-54831: GeoDirectory plugin version 2.8.162 and earlier contains an unauthenticated SQL injection vulnerability in the search functionality. This allows attackers to extract sensitive database information through crafted search queries. The vulnerability has a CVSS score of 7.5.nnThe root cause is insufficient input sanitization and unsafe SQL query construction in the `geodir-search` feature. The vulnerable code resides in `wp-content/plugins/geodirectory/includes/class-geodir-query.php` at lines 519-669. The function mishandles the search term variables `$s` and `$s_A`. In the vulnerable version, `$s_A` is passed through `wp_specialchars_decode()` but is then inserted directly into a SQL query on line 669 without proper parameterization via `$wpdb->prepare()`. The `$s_A` variable gets embedded into the `IN ($s_A)` clause, bypassing the `%s` placeholder. This allows SQL injection when the search term contains an ampersand character `&`.nnAn unauthenticated attacker can exploit this by sending a GET request to the WordPress site with a crafted search parameter `s` containing an ampersand along with injected SQL syntax. For example, the parameter `s=1&1=1 UNION SELECT …` triggers the vulnerable code path where `$s_A` receives the unparameterized value. The specific request path requires triggering the search endpoint that uses the GeoDirectory search widget or shortcode. The `strpos($s, ‘&’)` check on line 666 in the patched version indicates the vulnerability is triggered when the search term contains a literal ampersand character.nnThe patch in version 2.8.163 addresses the vulnerability by removing the `wp_specialchars_decode()` call on `$s_A` (commented out on line 522). This prevents HTML entity decoding that could transform encoded ampersands into raw ones. Additionally, the patch adds explicit handling for search terms containing an ampersand by checking `strpos($s, ‘&’)`. When an ampersand is present, the code now escapes the `$s_A` variable using `str_replace()` to convert ampersands to HTML entities before insertion into the `IN ()` clause. This ensures the database receives safe, expected values rather than interpreted SQL.nnSuccessful exploitation allows an unauthenticated attacker to execute arbitrary SQL queries against the WordPress database. This can lead to complete data disclosure including usernames, password hashes, session tokens, and other sensitive information stored in the database. The SQL injection can also be used to modify database content, potentially leading to privilege escalation or full site compromise. Since the vulnerability requires no authentication, it poses a significant risk to all sites running the vulnerable plugin version.”,
“poc_php”: “n”,
“modsecurity_rule”: “# Atomic Edge WAF Rule – CVE-2026-54831n# Block unauthenticated SQL injection via the GeoDirectory search parameter `s` with ampersand.n# This rule matches requests to the WordPress main query with `geodir_search=1` and a search term containing an ampersand used for SQL injection.nnSecRule REQUEST_URI “@contains /” \n “id:202654831,phase:2,deny,status:403,msg:’CVE-2026-54831 GeoDirectory SQL Injection Attempt’,severity:’CRITICAL’,tag:’CVE-2026-54831′,chain”n SecRule ARGS_GET:geodir_search “@streq 1” “chain”n SecRule ARGS_GET:s “@rx [&]+.*(?:SELECT|UNION|INSERT|UPDATE|DELETE|DROP|OR|AND)” “t:urlDecode”n”
“`

Published : June 28, 2026
CVE-2026-54831: GeoDirectory – WP Business Directory Plugin and Classified Listings Directory <= 2.8.162 Unauthenticated SQL Injection PoC, Patch Analysis & Rule
CVE ID
CVE-2026-54831
Plugin
geodirectory
Severity
High
(CVSS 7.5)
CWE
89
Vulnerable Version
2.8.162
Patched Version
2.8.163
Disclosed
June 16, 2026
Analysis Overview
Differential between vulnerable and patched code
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
Code Diff
--- a/geodirectory/geodirectory.php
+++ b/geodirectory/geodirectory.php
@@ -11,7 +11,7 @@
* Plugin Name: GeoDirectory
* Plugin URI: https://wpgeodirectory.com/
* Description: GeoDirectory - Business Directory Plugin for WordPress.
- * Version: 2.8.162
+ * Version: 2.8.163
* Author: AyeCode - WP Business Directory Plugins
* Author URI: https://wpgeodirectory.com
* Text Domain: geodirectory
@@ -34,7 +34,7 @@
*
* @var string
*/
- public $version = '2.8.162';
+ public $version = '2.8.163';
/**
* GeoDirectory instance.
--- a/geodirectory/includes/class-geodir-query.php
+++ b/geodirectory/includes/class-geodir-query.php
@@ -519,7 +519,7 @@
$s = trim( $s );
$s = wp_specialchars_decode( $s, ENT_QUOTES );
- $s_A = wp_specialchars_decode( $s_A, ENT_QUOTES );
+ //$s_A = wp_specialchars_decode( $s_A, ENT_QUOTES ); // Already applied esc_sql() wp_specialchars_decode();
// Exact search with quotes
$gd_exact_search = false;
@@ -666,9 +666,20 @@
$content_where = apply_filters( "geodir_search_content_where", $content_where );
if ( $gd_exact_search ) {
- $terms_where = $wpdb->prepare( " AND ($wpdb->terms.name LIKE %s ) ", array( $wpdb->esc_like( $s ) ) );
+ if ( strpos( $s, '&' ) === false ) {
+ $terms_where = $wpdb->prepare( " AND ($wpdb->terms.name LIKE %s ) ", array( $wpdb->esc_like( $s ) ) );
+ } else {
+ $terms_where = $wpdb->prepare( " AND ($wpdb->terms.name LIKE %s OR $wpdb->terms.name LIKE %s ) ", array( $wpdb->esc_like( $s ), $wpdb->esc_like( str_replace( "&", "&", $s ) ) ) );
+ }
} else {
- $terms_where = $wpdb->prepare( " AND ($wpdb->terms.name LIKE %s OR $wpdb->terms.name LIKE %s OR $wpdb->terms.name IN ($s_A)) ", array( $wpdb->esc_like( $s ) . '%', '% '. $wpdb->esc_like( $s ) . '%' ) );
+ if ( strpos( $s, '&' ) === false ) {
+ $terms_where = $wpdb->prepare( " AND ($wpdb->terms.name LIKE %s OR $wpdb->terms.name LIKE %s OR $wpdb->terms.name IN ($s_A)) ", array( $wpdb->esc_like( $s ) . '%', '% '. $wpdb->esc_like( $s ) . '%' ) );
+ } else {
+ // WordPress stores term names by converting & to & in database.
+ $esc_s_A = str_replace( "&", "&", $s_A );
+
+ $terms_where = $wpdb->prepare( " AND ($wpdb->terms.name LIKE %s OR $wpdb->terms.name LIKE %s OR $wpdb->terms.name IN ($s_A) OR $wpdb->terms.name LIKE %s OR $wpdb->terms.name LIKE %s OR $wpdb->terms.name IN ($esc_s_A)) ", array( $wpdb->esc_like( $s ) . '%', '% '. $wpdb->esc_like( $s ) . '%', $wpdb->esc_like( str_replace( "&", "&", $s ) ) . '%', '% '. $wpdb->esc_like( str_replace( "&", "&", $s ) ) . '%' ) );
+ }
}
/**
Frequently Asked Questions
How Atomic Edge Works
Simple Setup. Powerful Security.
Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.
Trusted by Developers & Organizations






