CVE-2026-4429

OSM <= 6.1.15 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'marker_name' Shortcode Attribute

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
6.1.16
Patched in
1d
Time to patch

Description

The OSM – OpenStreetMap plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'marker_name' and 'file_color_list' shortcode attribute of the [osm_map_v3] shortcode in all versions up to and including 6.1.15. This is due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, 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:L/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=6.1.15
PublishedApril 8, 2026
Last updatedApril 9, 2026
Affected pluginosm

What Changed in the Fix

Changes introduced in v6.1.16

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2026-4429 - OSM Stored XSS ## 1. Vulnerability Summary The **OSM – OpenStreetMap** plugin for WordPress (versions <= 6.1.15) is vulnerable to **Authenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists within the handling of the `[osm_map_v3]` shortcode, speci…

Show full research plan

Research Plan: CVE-2026-4429 - OSM Stored XSS

1. Vulnerability Summary

The OSM – OpenStreetMap plugin for WordPress (versions <= 6.1.15) is vulnerable to Authenticated Stored Cross-Site Scripting (XSS). The vulnerability exists within the handling of the [osm_map_v3] shortcode, specifically through the marker_name and file_color_list attributes. Because the plugin fails to sanitize or escape these attributes before rendering them in the page's HTML or JavaScript context, an attacker with at least Contributor-level permissions can inject malicious scripts into posts or pages.

2. Attack Vector Analysis

  • Endpoint: WordPress Post/Page Editor (standard wp-admin/post.php or Gutenberg block editor).
  • Shortcode: [osm_map_v3]
  • Vulnerable Attributes: marker_name, file_color_list.
  • Authentication Level: Contributor or higher (any role capable of using shortcodes).
  • Vector: The payload is stored in the post_content table and executes whenever the post/page is viewed.

3. Code Flow

  1. Entry Point: When a post containing [osm_map_v3] is rendered, WordPress calls the shortcode handler.
  2. Registration: The shortcode is handled in osm_map_v3/osm-sc-osm_map_v3.php.
  3. Attribute Extraction:
    • Line 47: extract(shortcode_atts(array(... 'file_color_list' => 'NoColor', ... 'marker_name' => 'NoName', ...), $atts));
    • The variables $marker_name and $file_color_list now hold raw user-provided values.
  4. Processing:
    • Line 81: Attributes are passed to the cOsm_arguments constructor.
    • Line 160: $default_icon = new cOsm_icon($marker_name); is called if marker_size is not set.
  5. Sink: The variables are subsequently used to build the HTML and JavaScript that initializes the OpenLayers map. In version 6.1.15, these are reflected into the page without calling escaping functions like esc_attr() or esc_js().

4. Nonce Acquisition Strategy

This is a Stored XSS vulnerability via a shortcode. It does not require a plugin-specific AJAX nonce to exploit. The attacker only needs to be able to save a post.

  • The "exploit" happens during the rendering phase.
  • To set up the exploit, use the wp-cli to create a post as a Contributor.
  • To trigger the exploit, navigate to the post URL.

5. Exploitation Strategy

Step 1: Payload Selection

We will test two attributes: marker_name and file_color_list.

  • Payload A (Attribute breakout): "><script>alert('XSS_MARKER')</script>
  • Payload B (JS context breakout): ';alert('XSS_COLOR');//

Step 2: Test Data Setup (via WP-CLI)

Create a post as a contributor user containing the malicious shortcode.

# 1. Ensure a contributor user exists
wp user create contributor contributor@example.com --role=contributor --user_pass=password123

# 2. Create a post with the malicious shortcode
wp post create --post_type=post \
               --post_title="OSM Map Test" \
               --post_status=publish \
               --post_author=$(wp user get contributor --field=ID) \
               --post_content='[osm_map_v3 marker_name="\"><script>alert(document.domain)</script>" file_color_list="\"><script>alert(window.origin)</script>"]'

Step 3: Trigger the Exploit

Navigate to the newly created post in the browser context.

// PoC Agent: Use browser_navigate to the URL of the created post.
// The post ID can be captured from the 'wp post create' output.

6. Test Data Setup

  • Plugin Status: OSM v6.1.15 installed and activated.
  • User Role: A user with edit_posts capability (Contributor+).
  • Content: A post containing the [osm_map_v3] shortcode with payloads in marker_name and/or file_color_list.

7. Expected Results

  • When the post is viewed, the HTML source should contain the unescaped script tags.
  • The browser should trigger the alert() functions.
  • Inspection of the DOM should show the script injected either into a data-* attribute of a div (breaking out with ">) or within a <script> block.

8. Verification Steps

  1. DOM Inspection: Use browser_eval to check for the presence of the injected payload in the rendered page.
    // Check if the script was rendered
    const scripts = Array.from(document.getElementsByTagName('script'));
    const xssFound = scripts.some(s => s.textContent.includes('alert(document.domain)'));
    return xssFound;
    
  2. HTML Source Check: Use http_request to fetch the post HTML and grep for the raw payload to confirm lack of encoding.
    # Expected: The response body contains the raw string:
    # marker_name=""><script>alert(document.domain)</script>"
    

9. Alternative Approaches

If the plugin renders these attributes inside a JSON object passed to wp_localize_script, the breakout payload might need to be adjusted:

  • JS Object Payload: "},alert(1),{"a":"
  • Broken Attribute Payload: marker_name="123' onclick='alert(1)'"

If marker_name is passed to the cOsm_icon class (as seen in line 160 of osm-sc-osm_map_v3.php), the vulnerability may manifest when the icon URL is generated in osm-icon-class.php. If the icon name is appended to a URL string without sanitization, an XSS via the src attribute of an <img> tag is possible:

  • Payload: x" onerror="alert(1)"

Check if your site is affected.

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