CVE-2026-56011

MapPress Maps for WordPress <= 2.97.3 - Unauthenticated Stored Cross-Site Scripting

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
2.97.4
Patched in
5d
Time to patch

Description

The MapPress Maps for WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 2.97.3 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.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.97.3
PublishedJune 19, 2026
Last updatedJune 23, 2026

What Changed in the Fix

Changes introduced in v2.97.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets **CVE-2026-56011**, an unauthenticated stored Cross-Site Scripting (XSS) vulnerability in the MapPress Maps for WordPress plugin. The vulnerability stems from a lack of capability checks in AJAX handlers that allow unauthenticated users to save or update map data, combined…

Show full research plan

This research plan targets CVE-2026-56011, an unauthenticated stored Cross-Site Scripting (XSS) vulnerability in the MapPress Maps for WordPress plugin. The vulnerability stems from a lack of capability checks in AJAX handlers that allow unauthenticated users to save or update map data, combined with insufficient output escaping in the map rendering logic.

1. Vulnerability Summary

  • Vulnerability: Unauthenticated Stored XSS.
  • Location: The vulnerability resides in the AJAX handlers registered in mappress_api.php (specifically those lacking current_user_can checks) and the rendering logic in mappress_map.php / mappress_poi.php.
  • Cause: The plugin registers wp_ajax_nopriv_ versions of map-saving actions. These actions do not verify that the requester has the edit_posts or manage_options capability. Furthermore, the to_html() methods for Maps and POIs (Points of Interest) do not properly escape all fields (like POI body content) before outputting them to the page.

2. Attack Vector Analysis

  • Vulnerable Endpoint: /wp-admin/admin-ajax.php.
  • Action: mapp_save (inferred action for saving/creating maps).
  • HTTP Parameter: map (JSON string containing map and POI data).
  • Authentication: Unauthenticated (No login required).
  • Preconditions: The site must have the plugin active. The exploit is more effective if a MapPress map or "Mashup" is already displayed on a public page, or if the attacker can identify the oid (Object ID) of an existing post to attach a map to.

3. Code Flow

  1. Entry Point: An unauthenticated attacker sends a POST request to admin-ajax.php with action=mapp_save.
  2. Dispatch: WordPress matches the action to the handler registered via add_action('wp_ajax_nopriv_mapp_save', ...) in mappress_api.php.
  3. Lack of Authorization: The handler in mappress_api.php processes the request without calling current_user_can().
  4. Data Processing: The handler parses the map JSON parameter. It may call new Mappress_Map($json_data) and then $map->save().
  5. Persistence: The save() method (in mappress_obj.php or mappress_db.php) writes the unsanitized or insufficiently sanitized POI titles/bodies to the {wp_prefix}mappress_maps or {wp_prefix}mappress_posts tables.
  6. Rendering (Sink): When a user views the post/page, Mappress_Map::to_html() is called (likely via the_content filter). It iterates through POIs, calling $poi->to_html().
  7. Execution: If $poi->to_html() returns the POI body or title without esc_html() or wp_kses(), the injected <script> executes in the victim's browser.

4. Nonce Acquisition Strategy

MapPress uses wp_localize_script to pass configuration and nonces to the frontend.

  • Shortcode: The plugin's scripts are typically enqueued when the [mappress] shortcode is present.
  • Strategy:
    1. Create a sacrificial page with the shortcode: wp post create --post_type=page --post_status=publish --post_title="Map" --post_content='[mappress]'.
    2. Navigate to this page.
    3. Extract the nonce from the mapp_data (inferred) JavaScript object.
  • JS Variable: window.mapp_data?.nonce or window.mappress_data?.nonce.
  • Verification: Check the mappress.php or mappress_map.php files for calls to wp_create_nonce. If check_ajax_referer is called in the save handler, the action string must match the one used in wp_create_nonce.

5. Exploitation Strategy

  1. Setup: Place a map on a page to identify its structure.
  2. Payload Preparation: Create a JSON object representing a Map with a malicious POI.
    {
      "title": "Normal Map",
      "pois": [
        {
          "title": "XSS",
          "body": "Location info<script>alert(document.domain)</script>",
          "point": {"lat": 0, "lng": 0}
        }
      ]
    }
    
  3. HTTP Request:
    • Method: POST
    • URL: http://example.com/wp-admin/admin-ajax.php
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body:
      action=mapp_save&_wpnonce=[NONCE]&map={"title":"XSS_Map","pois":[{"title":"XSS","body":"<img src=x onerror=alert(1)>"}]}
      
  4. Injection: If the response is a JSON success message (e.g., {"success": true, "mapid": 123}), the XSS is stored.

6. Test Data Setup

  • Plugin: Install MapPress Maps for WordPress v2.97.3.
  • Content: Create one public post with ID 1.
  • Shortcode: wp post create --post_type=page --post_status=publish --post_content='[mappress]' to ensure nonces are generated and scripts are loaded.

7. Expected Results

  • The admin-ajax.php request returns a 200 OK with a success status, even though no cookies are sent.
  • When navigating to the page where the map is rendered, an alert box appearing with 1 (or document.domain) confirms the Stored XSS.

8. Verification Steps

  1. DB Check: Use wp db query "SELECT title, body FROM wp_mappress_maps" (or the appropriate table identified in mappress_db.php) to confirm the payload is stored verbatim.
  2. Log Check: Verify no "Forbidden" or "403" errors occurred during the AJAX POST.
  3. Render Check: View the source of the page containing the map and look for the raw <img src=x onerror=alert(1)> inside the mappress-map component or POI list.

9. Alternative Approaches

  • REST API: If the AJAX actions are secured but the plugin registered REST routes in mappress_api.php, check register_rest_route for missing permission_callback arguments (or those returning __return_true).
  • POI List XSS: Some templates render a list of POIs below the map. Check templates/mashup-modal.php or mappress_template.php to see if the body field is escaped there.
  • Map Alignment/Class: In mappress_map.php, the $class and $alignment variables are part of the object. Test if these can be used to break out of the <mappress-map> attributes: map={"class": '"><script>alert(1)</script>'}.
Research Findings
Static analysis — not yet PoC-verified

Summary

The MapPress Maps for WordPress plugin is vulnerable to unauthenticated stored Cross-Site Scripting due to a lack of authorization checks in its AJAX saving routines and insufficient output escaping of map attributes. An attacker can submit a malicious map configuration containing JavaScript, which is then executed in the context of any user viewing a page where the map is rendered.

Vulnerable Code

// mappress_map.php line 56
$name = (isset($vars['name']) ? $vars['name'] : 'noname');

// ...

// mappress_map.php line 59
return "<div></div>\r\n<mappress-map id={$name} {$atts}>\r\n$pois\r\n</mappress-map>\r\n";

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/mappress-google-maps-for-wordpress/2.97.3/mappress_map.php /home/deploy/wp-safety.org/data/plugin-versions/mappress-google-maps-for-wordpress/2.97.4/mappress_map.php
--- /home/deploy/wp-safety.org/data/plugin-versions/mappress-google-maps-for-wordpress/2.97.3/mappress_map.php	2026-06-11 02:40:52.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/mappress-google-maps-for-wordpress/2.97.4/mappress_map.php	2026-06-11 02:40:52.000000000 +0000
@@ -56,7 +56,7 @@
 		$name = (isset($vars['name']) ? $vars['name'] : 'noname');
 		
 		// Extra div forces web component out of phrasing elements like <p>
-		return "<div></div>\r\n<mappress-map id={$name} {$atts}>\r\n$pois\r\n</mappress-map>\r\n";
+		return "<div></div>\r\n<mappress-map id=\"" . esc_attr($name) . "\" {$atts}>\r\n$pois\r\n</mappress-map>\r\n";        
 	}

Exploit Outline

An unauthenticated attacker sends a POST request to admin-ajax.php with the action 'mapp_save' (or similar map-saving action), which is registered for unauthenticated users via wp_ajax_nopriv_ but lacks authorization checks. The attacker includes a 'map' JSON parameter containing a malicious payload in fields like the map 'name' or POI 'body'. When the map is subsequently rendered on a page via the [mappress] shortcode, the plugin's to_html() method in mappress_map.php outputs the unsanitized map ID and attributes directly into the HTML, triggering the stored script in the context of the victim's browser.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.