[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fQyF1NgIcwnU7Fw6R7m5IM86X2eoe2K8fDDgVD2lDqwQ":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-8385","wp-go-maps-unauthenticated-sensitive-information-disclosure-via-datatables-ajax-fallback","WP Go Maps \u003C 10.0.10 - Unauthenticated Sensitive Information Disclosure via Datatables AJAX Fallback","The WP Go Maps plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 10.0.09 via the datatables AJAX fallback route. This makes it possible for unauthenticated attackers to extract  marker records that the site owner has not approved for public display, including their title, category, address and description fields.","wp-google-maps",null,"\u003C=10.0.09","10.0.10","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:L\u002FI:N\u002FA:N","Exposure of Sensitive Information to an Unauthorized Actor","2026-06-05 00:00:00","2026-06-05 12:31:17",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fde64e79f-0284-4d23-a18b-64554f2b188e?source=api-prod",1,[22,23,24,25,26,27,28,29],"html\u002Fsettings-page.html.php","includes\u002Fclass.installer-page.php","includes\u002Fclass.plugin.php","includes\u002Fclass.rest-api.php","includes\u002Fclass.settings-page.php","includes\u002Fcompat\u002Fclass.pro-10-compatibility.php","includes\u002Ftables\u002Fclass.marker-datatable.php","readme.txt","researched",false,3,"# Exploitation Research Plan: CVE-2026-8385\n\n## 1. Vulnerability Summary\nThe **WP Go Maps** plugin (versions \u003C= 10.0.09) contains a sensitive information disclosure vulnerability within its DataTables AJAX fallback mechanism. The core issue is a logical flaw in how the plugin determines if a request is \"administrative.\" In `WPGMZA\\MarkerDataTable::getWhereClause`, the code uses `is_admin()` to decide whether to filter out unapproved markers. In WordPress, `is_admin()` returns `true` for all requests to `admin-ajax.php`, including unauthenticated (`nopriv`) requests. Consequently, an unauthenticated attacker can access the AJAX fallback route to retrieve marker data—including title, address, and description—that has not been approved for public display.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action:** `wpgmza_rest_api_request` (Registered in `includes\u002Fclass.rest-api.php` via `wp_ajax_nopriv_wpgmza_rest_api_request`)\n*   **Method:** `GET` or `POST`\n*   **Authentication:** None (Unauthenticated)\n*   **Vulnerable Parameter:** `short_route` (used to target the `datatables` logic)\n*   **Preconditions:** The plugin must be active. At least one \"unapproved\" marker must exist in the database (e.g., a visitor-generated marker awaiting moderation).\n\n## 3. Code Flow\n1.  **Entry Point:** An unauthenticated request is sent to `admin-ajax.php` with `action=wpgmza_rest_api_request`.\n2.  **Fallback Logic:** `WPGMZA\\RestAPI::onAJAXRequest` (in `includes\u002Fclass.rest-api.php`) receives the request. It identifies the intended route based on the `short_route` or URL parameters.\n3.  **Route Registration:** In `includes\u002Fclass.rest-api.php`, the `datatables` route is registered via `registerRoute()`. Crucially, lines 135-139 explicitly skip nonce checks for the `datatables` route:\n    ```php\n    $skipNonceRoutes = array('features', 'markers', 'marker-listing', 'datatables');\n    if(in_array(str_replace('\u002F', '', $route), $skipNonceRoutes)){\n        $doActionNonceCheck = false;\n    }\n    ```\n4.  **Table Instantiation:** The request triggers the DataTables handler, which instantiates `WPGMZA\\MarkerDataTable`.\n5.  **Vulnerable Sink:** `WPGMZA\\MarkerDataTable::getWhereClause` (in `includes\u002Ftables\u002Fclass.marker-datatable.php`) executes:\n    ```php\n    if(!(is_admin() || (isset($_SERVER['HTTP_REFERER']) && preg_match('\u002Fpage=wp-google-maps-menu\u002F', $_SERVER['HTTP_REFERER']) && $wpgmza->isUserAllowedToEdit())))\n    {\n        $clause .= ' AND approved=%d';\n        $query_params[] = 1;\n    }\n    ```\n6.  **Logic Failure:** Since the request is processed via `admin-ajax.php`, `is_admin()` returns `true`. The `if` condition evaluates to `false`, the `approved=1` clause is **not** appended, and the database query returns all markers, including unapproved ones.\n\n## 4. Nonce Acquisition Strategy\nNo nonce is required for this exploit. As identified in `includes\u002Fclass.rest-api.php` (Line 137), the `datatables` route is explicitly added to the `$skipNonceRoutes` array, and the AJAX action is registered as `wp_ajax_nopriv_wpgmza_rest_api_request`.\n\n## 5. Exploitation Strategy\nThe goal is to invoke the `datatables` fallback route for the `MarkerDataTable` class.\n\n1.  **Request Type:** POST (to bypass potential GET length limits and follow the fallback structure).\n2.  **URL:** `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php`\n3.  **Payload Parameters:**\n    *   `action`: `wpgmza_rest_api_request`\n    *   `short_route`: `\u002Fdatatables`\n    *   `php_class`: `WPGMZA\\\\MarkerDataTable`\n    *   `draw`: `1` (Standard DataTables parameter)\n    *   `start`: `0`\n    *   `length`: `10`\n4.  **Action:** Send the request using the `http_request` tool.\n\n## 6. Test Data Setup\nTo verify the disclosure, markers with `approved = 0` must exist.\n1.  **Create an Unapproved Marker:**\n    ```bash\n    wp db query \"INSERT INTO wp_wpgmza (title, address, description, approved, lat, lng) VALUES ('Secret Location', '123 Hidden St', 'Sensitive Data', 0, '0.000000', '0.000000');\"\n    ```\n2.  **Verify Setup:**\n    ```bash\n    wp db query \"SELECT id, title, approved FROM wp_wpgmza WHERE approved = 0;\"\n    ```\n\n## 7. Expected Results\n*   **Response Code:** `200 OK`\n*   **Response Body:** A JSON object containing a `data` array (DataTables format).\n*   **Indicator of Success:** The `data` array contains the entry for \"Secret Location\" despite it being unapproved.\n\n## 8. Verification Steps\nAfter the HTTP request, check the response body for the sensitive marker:\n1.  Use `jq` or a similar tool to parse the response from the `http_request` tool.\n2.  Confirm the presence of markers where `approved` is logically `0`.\n3.  Validate that the same marker is **not** visible on the frontend map (which uses a different, properly filtered REST endpoint).\n\n## 9. Alternative Approaches\nIf the `php_class` parameter is restricted, the attacker can attempt to reach the endpoint by mimicking the standard REST API path structure through the `short_route` parameter, e.g., `short_route=markers` if that route also utilizes a vulnerable DataTable class without proper capability checks.\n\n## 10. Remediation Recommendation\nThe use of `is_admin()` for security checks in AJAX handlers should be replaced with `current_user_can('manage_options')` or a specific plugin capability (e.g., `$wpgmza->isUserAllowedToEdit()`). This ensures that only users with actual administrative privileges—rather than any request hitting the administrative AJAX endpoint—can bypass marker approval filters.","The WP Go Maps plugin is vulnerable to unauthenticated sensitive information disclosure due to a logic flaw in its DataTables AJAX fallback mechanism. By exploiting the fact that is_admin() returns true for all admin-ajax.php requests, attackers can retrieve marker data that has not been approved for public display.","\u002F\u002F includes\u002Ftables\u002Fclass.marker-datatable.php:33\nprotected function getWhereClause($input_params, &$query_params, $clause_for_total=false)\n{\n    global $wpgmza;\n    \n    $clause = AjaxTable::getWhereClause($input_params, $query_params, $clause_for_total);\n    \n    if(!(is_admin() || (isset($_SERVER['HTTP_REFERER']) && preg_match('\u002Fpage=wp-google-maps-menu\u002F', $_SERVER['HTTP_REFERER']) && $wpgmza->isUserAllowedToEdit())))\n    {\n        $clause .= ' AND approved=%d';\n        $query_params[] = 1;\n    }\n    \n    return $clause;\n}\n\n---\n\n\u002F\u002F includes\u002Fclass.rest-api.php:135\n$skipNonceRoutes = array('features', 'markers', 'marker-listing', 'datatables');\nif(in_array(str_replace('\u002F', '', $route), $skipNonceRoutes)){\n    $doActionNonceCheck = false;\n}","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-google-maps\u002F10.0.09\u002Fincludes\u002Ftables\u002Fclass.marker-datatable.php\t2026-04-16 15:28:10.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-google-maps\u002F10.0.10\u002Fincludes\u002Ftables\u002Fclass.marker-datatable.php\t2026-05-13 08:10:24.000000000 +0000\n@@ -30,7 +30,7 @@\n \t\t\n \t\t$clause = AjaxTable::getWhereClause($input_params, $query_params, $clause_for_total);\n \t\t\n-\t\tif(!(is_admin() || (isset($_SERVER['HTTP_REFERER']) && preg_match('\u002Fpage=wp-google-maps-menu\u002F', $_SERVER['HTTP_REFERER']) && $wpgmza->isUserAllowedToEdit())))\n+\t\tif(!((isset($_SERVER['HTTP_REFERER']) && preg_match('\u002Fpage=wp-google-maps-menu\u002F', $_SERVER['HTTP_REFERER']) && $wpgmza->isUserAllowedToEdit())))\n \t\t{\n \t\t\t$clause .= ' AND approved=%d';\n \t\t\t$query_params[] = 1;\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-google-maps\u002F10.0.09\u002Fincludes\u002Fclass.rest-api.php\t2026-04-16 15:28:10.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-google-maps\u002F10.0.10\u002Fincludes\u002Fclass.rest-api.php\t2026-05-13 08:10:24.000000000 +0000\n@@ -838,6 +838,12 @@\n \t\t\t\tif(preg_match('#\u002Fwpgmza\u002Fv1\u002Fmarkers\u002F(\\d+)#', $route, $m)) {\n \t\t\t\t\ttry{\n \t\t\t\t\t\t$marker = Marker::createInstance($m[1], Crud::SINGLE_READ, isset($_GET['raw_data']));\n+\n+\t\t\t\t\t\tif(empty($marker->approved) && !$wpgmza->isUserAllowedToEdit()){\n+\t\t\t\t\t\t\t\u002F* Marker is not approved *\u002F\n+\t\t\t\t\t\t\treturn new \\WP_Error('wpgmza_marker_not_found', 'Marker does not exist', array('status' => 404));\n+\t\t\t\t\t\t}\n+\n \t\t\t\t\t\treturn $marker;\n \t\t\t\t\t} catch (\\Exception $ex){\n \t\t\t\t\t\treturn new \\WP_Error('wpgmza_marker_not_found', 'Marker does not exist', array('status' => 404));","The exploit targets the AJAX fallback route 'wpgmza_rest_api_request' via \u002Fwp-admin\u002Fadmin-ajax.php. An unauthenticated attacker sends a POST request with 'short_route' set to '\u002Fdatatables' and 'php_class' set to 'WPGMZA\\\\MarkerDataTable'. Because the plugin uses is_admin() to determine whether to apply the 'approved=1' filter, and is_admin() returns true for all admin-ajax.php requests, the database query returns all markers including those pending approval. No nonce is required as the 'datatables' route is explicitly excluded from nonce checks.","gemini-3-flash-preview","2026-06-26 04:28:27","2026-06-26 04:29:47",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","10.0.09","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-google-maps\u002Ftags\u002F10.0.09","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-google-maps.10.0.09.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-google-maps\u002Ftags\u002F10.0.10","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-google-maps.10.0.10.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-google-maps\u002Ftags"]