GeekyBot — AI Copilot, Chatbot, WooCommerce Lead Gen & Zero-Prompt Content <= 1.2.0 - Unauthenticated SQL Injection
Description
The GeekyBot — AI Copilot, Chatbot, WooCommerce Lead Gen & Zero-Prompt Content plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 1.2.0 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:NTechnical Details
What Changed in the Fix
Changes introduced in v1.2.1
Source Code
WordPress.org SVNThis research plan outlines the steps to exploit an unauthenticated SQL injection vulnerability in the **GeekyBot** plugin for WordPress (versions <= 1.2.0). ### 1. Vulnerability Summary The GeekyBot plugin is vulnerable to SQL injection because it uses the `geekybot_chat_id` cookie value directly …
Show full research plan
This research plan outlines the steps to exploit an unauthenticated SQL injection vulnerability in the GeekyBot plugin for WordPress (versions <= 1.2.0).
1. Vulnerability Summary
The GeekyBot plugin is vulnerable to SQL injection because it uses the geekybot_chat_id cookie value directly in SQL queries without sanitization or parameterization via $wpdb->prepare(). Specifically, the value is retrieved via geekybot_getchatid() and concatenated into queries in includes/classes/geekybotsessiondata.php. Since this cookie can be set by any unauthenticated user, it provides a direct path for SQL injection.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
geekybot_process_message(unauthenticated AJAX action) - Vulnerable Parameter:
geekybot_chat_idCookie - Authentication: Unauthenticated
- Preconditions: None. The plugin just needs to be active.
3. Code Flow
- Entry Point: An unauthenticated user sends a request to
admin-ajax.phpwith the actiongeekybot_process_message. - AJAX Handler: The handler (likely in
geeky-bot.php) calls the chatbot logic to process the message. - Session Initialization: The code attempts to load or save session data using
GEEKYBOTgeekybotsessiondata::geekybot_addSessionVariablesDataToTableorgeekybot_getVariablesDatabySessionId(found inincludes/classes/geekybotsessiondata.php). - Source: These functions call
GEEKYBOTchathistoryModel::geekybot_getchatid()which retrieves the value of$_COOKIE['geekybot_chat_id']. - Sink: The value is concatenated into a raw SQL query string:
// includes/classes/geekybotsessiondata.php $query = "SELECT sessionmsgvalue FROM `" . geekybot::$_db->prefix . "geekybot_sessiondata` WHERE sessionmsgkey = '" . $key . "' AND usersessionid = '" . $chatid . "' AND sessionexpire > '" . time() . "'"; $data = geekybotdb::GEEKYBOT_get_row($query); - Execution:
geekybotdb::GEEKYBOT_get_rowexecutes the unsanitized query, leading to SQL injection.
4. Nonce Acquisition Strategy
The chatbot typically requires a nonce for its AJAX requests. This nonce is usually localized into the page's JavaScript.
- Identify Shortcode: The chatbot is often site-wide but may require the
[geeky-bot]or[geekybot]shortcode. - Create Page:
wp post create --post_type=page --post_status=publish --post_content='[geekybot]' - Navigate and Extract:
- Use
browser_navigateto visit the new page. - Use
browser_evalto extract the nonce:// Common variable name for this plugin's
- Use
Summary
The GeekyBot plugin for WordPress is vulnerable to unauthenticated SQL injection due to the use of unsanitized values from the 'geekybot_chat_id' cookie in database queries. Attackers can manipulate this cookie to append arbitrary SQL commands to existing queries, potentially allowing for the extraction of sensitive information from the database.
Vulnerable Code
// includes/classes/geekybotsessiondata.php public function geekybot_addSessionVariablesDataToTable($messages){ // ... (lines 21-23) if(isset($_COOKIE['geekybot_chat_id'])){ $chatid = GEEKYBOTincluder::GEEKYBOT_getModel('chathistory')->geekybot_getchatid(); foreach ($messages as $key => $value) { $value = addslashes($value); if ($key != 'chathistory') { $data = $this->geekybot_getVariablesDatabySessionId($chatid, $key); if($data != ""){ $update = true; } else { $update = false; } if(!$update){ $query = "INSERT INTO `" . geekybot::$_db->prefix . "geekybot_sessiondata` (`usersessionid`, `sessionmsgkey`, `sessionmsgvalue`, `sessionexpire`) VALUES ('".$chatid."', '".$key."', '".$value."', '".geekybot::$_geekybotsession->sessionexpire."');"; geekybot::$_db->query($query); }else{ $query = "UPDATE `" . geekybot::$_db->prefix . "geekybot_sessiondata` SET `sessionmsgvalue` = '".$value."' WHERE `usersessionid`= '" . $chatid . "' AND `sessionmsgkey`= '" . $key . "' "; geekybotdb::query($query); } } } } return false; } --- // includes/classes/geekybotsessiondata.php public function geekybot_getVariablesDatabySessionId($usersessionid, $key = '' , $deldata = false){ $query = "SELECT sessionmsgvalue FROM `" . geekybot::$_db->prefix . "geekybot_sessiondata` WHERE sessionmsgkey = '" . $key . "' AND usersessionid = '" . $usersessionid . "' AND sessionexpire > '" . time() . "'"; $data = geekybotdb::GEEKYBOT_get_row($query); if($deldata){ $query = "DELETE FROM `".geekybot::$_db->prefix . "geekybot_sessiondata` WHERE usersessionid = '".$usersessionid."' "; geekybotdb::query($query); } return $data; }
Security Fix
@@ -21,9 +21,13 @@ $update = false; if(isset($_COOKIE['geekybot_chat_id'])){ $chatid = GEEKYBOTincluder::GEEKYBOT_getModel('chathistory')->geekybot_getchatid(); + $chatid = esc_sql( sanitize_text_field($chatid) ); foreach ($messages as $key => $value) { $value = addslashes($value); if ($key != 'chathistory') { + $key = esc_sql( sanitize_text_field($key) ); + $value = esc_sql( sanitize_text_field($value) ); + $data = $this->geekybot_getVariablesDatabySessionId($chatid, $key); if($data != ""){ $update = true; @@ -31,7 +35,8 @@ $update = false; } if(!$update){ - $query = "INSERT INTO `" . geekybot::$_db->prefix . "geekybot_sessiondata` (`usersessionid`, `sessionmsgkey`, `sessionmsgvalue`, `sessionexpire`) VALUES ('".$chatid."', '".$key."', '".$value."', '".geekybot::$_geekybotsession->sessionexpire."');"; + $sessionexpire = esc_sql( sanitize_text_field(geekybot::$_geekybotsession->sessionexpire) ); + $query = "INSERT INTO `" . geekybot::$_db->prefix . "geekybot_sessiondata` (`usersessionid`, `sessionmsgkey`, `sessionmsgvalue`, `sessionexpire`) VALUES ('".$chatid."', '".$key."', '".$value."', '".$sessionexpire."');"; geekybot::$_db->query($query); }else{ $query = "UPDATE `" . geekybot::$_db->prefix . "geekybot_sessiondata` SET `sessionmsgvalue` = '".$value."' WHERE `usersessionid`= '" . $chatid . "' AND `sessionmsgkey`= '" . $key . "' "; @@ -60,8 +76,14 @@ } public function geekybot_getVariablesDatabySessionId($usersessionid, $key = '' , $deldata = false){ + $usersessionid = esc_sql( sanitize_text_field($usersessionid) ); + $key = esc_sql( sanitize_text_field($key) ); + $time = time(); + $query = "SELECT sessionmsgvalue - FROM `" . geekybot::$_db->prefix . "geekybot_sessiondata` WHERE sessionmsgkey = '" . $key . "' AND usersessionid = '" . $usersessionid . "' AND sessionexpire > '" . time() . "'"; + FROM `" . geekybot::$_db->prefix . "geekybot_sessiondata` WHERE sessionmsgkey = '" . $key . "' AND usersessionid = '" . $usersessionid . "' AND sessionexpire > '" . $time . "'"; + $data = geekybotdb::GEEKYBOT_get_row($query); if($deldata){ $query = "DELETE FROM `".geekybot::$_db->prefix . "geekybot_sessiondata` WHERE usersessionid = '".$usersessionid."' ";
Exploit Outline
To exploit this vulnerability, an unauthenticated attacker needs to follow these steps: 1. **Locate Interaction Point**: Identify a page on the target WordPress site where the GeekyBot chatbot is active. This is common if the site uses the `[geekybot]` shortcode or has the chatbot globally enabled. 2. **Craft Payload**: Prepare a malicious SQL payload designed to extract data or cause delays (e.g., using `UNION SELECT` or boolean-based techniques). 3. **Set Cookie**: Inject the payload into the `geekybot_chat_id` cookie. Since the plugin retrieves this cookie via `geekybot_getchatid()` and concatenates it directly into SQL queries within `includes/classes/geekybotsessiondata.php`, the payload will be executed. 4. **Trigger Execution**: Send an AJAX request to `/wp-admin/admin-ajax.php` with the action `geekybot_process_message`. This action triggers the chatbot logic, which subsequently calls session management functions that utilize the malicious cookie value in database queries. 5. **Data Extraction**: Observe the server's response or use time-based analysis (if using a sleep-based payload) to confirm the execution of the injected SQL and extract database information.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.