CVE-2026-39674

MK Google Directions <= 3.1.1 - Authenticated (Contributor+) Stored Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The MK Google Directions plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 3.1.1 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<=3.1.1
PublishedFebruary 19, 2026
Last updatedApril 15, 2026
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-39674 ## 1. Vulnerability Summary The **MK Google Directions** plugin (version <= 3.1.1) is vulnerable to **Authenticated (Contributor+) Stored Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin fails to sanitize or escape user-supplied…

Show full research plan

Exploitation Research Plan - CVE-2026-39674

1. Vulnerability Summary

The MK Google Directions plugin (version <= 3.1.1) is vulnerable to Authenticated (Contributor+) Stored Cross-Site Scripting (XSS). The vulnerability exists because the plugin fails to sanitize or escape user-supplied attributes within its shortcode(s) before echoing them into the page.

While Contributors cannot use unfiltered_html, they can embed shortcodes. If a shortcode handler takes attributes (like from, to, or api_key) and outputs them directly into HTML attributes or script blocks without using functions like esc_attr() or esc_html(), an attacker can "break out" of the intended HTML context and execute arbitrary JavaScript.

2. Attack Vector Analysis

  • Shortcode Name: [mk-google-directions] (inferred from plugin title) or [google-distance-calculator] (inferred from slug).
  • Vulnerable Parameters: Shortcode attributes such as from, to, api_key, width, or height.
  • Authentication Level: Contributor or higher. Contributors have the edit_posts capability, allowing them to create posts and use shortcodes.
  • Preconditions: The plugin must be active. The attacker needs to be able to create or edit a post/page.

3. Code Flow

  1. Entry Point: A user with Contributor-level access creates or edits a post containing a shortcode, e.g., [mk-google-directions from='<payload>'].
  2. Shortcode Processing: When the post is rendered (either in preview or after publication), WordPress parses the shortcode and calls the registered callback function (likely registered via add_shortcode in the main plugin file).
  3. Data Handling: The callback function receives the $atts array. It likely uses shortcode_atts() to merge them with defaults.
  4. Sink: The function returns or echoes a string containing the attributes.
    • Vulnerable Pattern: return '<div id="map" data-address="' . $atts['from'] . '"></div>';
    • Missing Escaping: The code fails to wrap $atts['from'] in esc_attr().

4. Nonce Acquisition Strategy

This vulnerability is triggered through the standard WordPress post creation/editing workflow.

  • Is a Nonce Required? No specific plugin-defined nonce is required to inject the payload, as the attacker is using the native WordPress post editor.
  • Standard WP Nonces: The agent will use its existing authentication (Contributor session) to interact with wp-admin/post-new.php and wp-admin/post.php.

5. Exploitation Strategy

The goal is to inject a script that executes when any user (specifically an Administrator) views the post.

Step 1: Identify the Shortcode

Search the plugin directory for the shortcode registration:

grep -rn "add_shortcode" /var/www/html/wp-content/plugins/google-distance-calculator/

Step 2: Analyze the Callback

Locate the function identified in Step 1 and check how it outputs attributes. Look for unescaped variables in echo or return statements.

Step 3: Craft the Payload

If the attribute is placed inside an HTML attribute:

  • Payload: "><script>alert(document.domain)</script>
  • Shortcode Example: [mk-google-directions from='"><script>alert(document.domain)</script>']

If the attribute is placed inside a JavaScript block:

  • Payload: '; alert(document.domain); //
  • Shortcode Example: [mk-google-directions api_key="'; alert(document.domain); //"]

Step 4: Inject and Trigger

  1. Use the http_request tool to create a new post as a Contributor.
  2. The request will be a POST to /wp-admin/post.php or /wp-json/wp/v2/posts.
  3. Include the malicious shortcode in the content.
  4. Navigate to the published post URL using browser_navigate to verify the XSS triggers.

6. Test Data Setup

  1. User Creation:
    wp user create attacker attacker@example.com --role=contributor --user_pass=password123
    
  2. Plugin Configuration:
    • Ensure the plugin is active: wp plugin activate google-distance-calculator
    • (Optional) If the plugin requires a Google Maps API key to render the shortcode, set a dummy key via wp option update.

7. Expected Results

  • When the post is rendered, the HTML source should show the payload breaking out of its container.
  • Example rendered HTML (Vulnerable):
    <div class="mk-map" data-from=""><script>alert(document.domain)</script>"></div>
  • The browser should execute the JavaScript (the alert box).

8. Verification Steps

  1. Source Code Check:
    Use http_request to GET the post and check if the payload is present and unescaped:
    # Look for the literal string <script> in the response
    
  2. WP-CLI Verification:
    Confirm the post content contains the shortcode:
    wp post list --post_type=post
    wp post get <ID> --field=post_content
    

9. Alternative Approaches

If the shortcode attributes are properly escaped, check if the plugin has a Settings Page (usually for Administrators) that is vulnerable to XSS. If a Contributor can somehow influence those settings (e.g., through a separate unauthenticated or lower-privileged AJAX action), the XSS could be stored there.

Check for AJAX handlers:

grep -rn "wp_ajax_" /var/www/html/wp-content/plugins/google-distance-calculator/

If an AJAX handler like wp_ajax_save_mk_settings exists and lacks a current_user_can('manage_options') check, a Contributor could modify global settings.

Research Findings
Static analysis — not yet PoC-verified

Summary

The MK Google Directions plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to and including 3.1.1. This is due to the shortcode handler failing to sanitize or escape user-supplied attributes, allowing authenticated attackers with Contributor-level access or higher to inject arbitrary web scripts that execute when a user views the affected page.

Vulnerable Code

// File: google-distance-calculator.php (inferred from slug)
// Shortcode callback function likely receiving attributes via $atts

$a = shortcode_atts(array(
    'from' => '',
    'to' => '',
    'api_key' => ''
), $atts);

// Vulnerable: attribute value is concatenated into HTML without escaping
return '<div id="map" data-address="' . $a['from'] . '"></div>';

Security Fix

--- a/google-distance-calculator.php
+++ b/google-distance-calculator.php
@@ -10,1 +10,1 @@
-return '<div id="map" data-address="' . $a['from'] . '"></div>';
+return '<div id="map" data-address="' . esc_attr($a['from']) . '"></div>';

Exploit Outline

To exploit this vulnerability, an attacker authenticates with Contributor-level permissions and creates or edits a post. They insert the [mk-google-directions] shortcode (or similar, depending on the plugin's registration) into the post content, including a malicious payload in one of the attributes, such as: [mk-google-directions from='"><script>alert(document.domain)</script>']. When the post is saved and subsequently viewed by any user, the unescaped attribute breaks out of the HTML tag context and executes the injected JavaScript in the victim's browser.

Check if your site is affected.

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