CVE-2026-4803

Royal Addons for Elementor <= 1.7.1056 - Unauthenticated Stored Cross-Site Scripting via 'status' Parameter in wpr_update_form_action_meta

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
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 the 'status' parameter in the wpr_update_form_action_meta AJAX action in all versions up to, and including, 1.7.1056. This is due to insufficient input sanitization and output escaping, combined with a publicly leaked nonce that allows unauthenticated access to the AJAX handler. This makes it possible for unauthenticated attackers 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:N/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.7.1056
PublishedMay 4, 2026
Last updatedMay 5, 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

This research plan targets a Stored Cross-Site Scripting (XSS) vulnerability in **Royal Addons for Elementor** (CVE-2026-4803). The vulnerability exists in the `wpr_update_form_action_meta` AJAX action due to a lack of sanitization on the `status` parameter and a nonce that is exposed to unauthentic…

Show full research plan

This research plan targets a Stored Cross-Site Scripting (XSS) vulnerability in Royal Addons for Elementor (CVE-2026-4803). The vulnerability exists in the wpr_update_form_action_meta AJAX action due to a lack of sanitization on the status parameter and a nonce that is exposed to unauthenticated users.


1. Vulnerability Summary

  • ID: CVE-2026-4803
  • Vulnerability Type: Stored Cross-Site Scripting (XSS)
  • Root Cause: The function wpr_update_form_action_meta (likely located in modules/form-builder/module.php or a similar backend handler) accepts a status parameter via AJAX. This value is saved to post metadata using update_post_meta() without sanitization and subsequently rendered in the WordPress admin dashboard (Form Submissions or Form Settings) without escaping.
  • Authentication: Unauthenticated (via wp_ajax_nopriv_ registration and a leaked nonce).

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: wpr_update_form_action_meta
  • Vulnerable Parameter: status
  • Nonce Variable: WprConfig.nonce (found in the localized script object on the frontend).
  • Required Parameters:
    • action: wpr_update_form_action_meta
    • nonce: Valid WP nonce for the wpr-addons-nonce action.
    • post_id: The ID of a post (likely an REA Form or a template).
    • status: The XSS payload.
    • action_type: (Inferred) Likely required to specify which form action meta to update (e.g., email, mailchimp).

3. Code Flow

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php with action=wpr_update_form_action_meta.
  2. Nonce Verification: The handler calls check_ajax_referer( 'wpr-addons-nonce', 'nonce' ). Since the wpr-addons-nonce is localized into the WprConfig object on all frontend pages containing REA widgets, it is "publicly leaked."
  3. Data Processing: The function retrieves $_POST['status'] and $_POST['post_id'].
  4. Persistence: The unsanitized status value is stored:
    update_post_meta( $post_id, '_wpr_form_action_' . $action_type . '_status', $status ); (Inferred logic).
  5. Execution: An administrator navigates to the "Royal Addons -> Form Submissions" or the Elementor editor for the specific form. The stored status is echoed back into the page:
    echo get_post_meta( $id, '...', true ); (Lack of esc_html or esc_attr).

4. Nonce Acquisition Strategy

The nonce is localized in the WprConfig global JS variable on any page where Royal Elementor Addons scripts are loaded.

  1. Trigger Script Loading: REA scripts load when a widget is present. We will use the [wpr_button] shortcode as a lightweight trigger.
  2. Creation: Use WP-CLI to create a public page with the shortcode.
  3. Extraction: Navigate to the page and use browser_eval to extract the nonce.
  • JS Variable: window.WprConfig
  • Nonce Key: nonce
  • Command: browser_eval("window.WprConfig?.nonce")

5. Exploitation Strategy

Step 1: Identify a Target Post ID

We need a valid ID to attach the metadata to. We can target an existing post or create a dummy one.

  • Tool: wp_cli
  • Command: wp post list --post_type=post --format=ids | head -n 1

Step 2: Acquire Nonce

  1. Create a trigger page: wp post create --post_type=page --post_title="XSS Trigger" --post_status=publish --post_content='[wpr_button text="Click Me"]'
  2. Navigate to the page using browser_navigate.
  3. Execute browser_eval("window.WprConfig.nonce") to retrieve the nonce.

Step 3: Inject Payload

Send the malicious AJAX request.

  • Method: POST
  • URL: http://[target]/wp-admin/admin-ajax.php
  • Content-Type: application/x-www-form-urlencoded
  • Parameters:
    • action: wpr_update_form_action_meta
    • nonce: [EXTRACTED_NONCE]
    • post_id: [TARGET_ID]
    • action_type: email (Commonly used in form actions)
    • status: <script>alert("CVE-2026-4803_XSS")</script>

Step 4: Verification (Admin Context)

  1. Log in as administrator using browser_navigate.
  2. Navigate to the post editor or REA settings where form actions are displayed.
  3. Check for the execution of the alert.

6. Test Data Setup

  1. Install Plugin: Ensure royal-elementor-addons version <= 1.7.1056 is installed.
  2. Create Form: (Optional but recommended) Create a simple Royal Addons form via Elementor to ensure the metadata fields exist.
  3. Trigger Page: Create a page with [wpr_button] to leak the nonce.

7. Expected Results

  • AJAX Response: Should return 1 or a success JSON (e.g., {"success":true}).
  • Admin UI: When viewing the settings for the targeted post_id, the script should execute.

8. Verification Steps (Post-Exploit)

After the HTTP request, verify the metadata is actually in the database:

  • Command: wp post meta list [POST_ID]
  • Check: Look for any key starting with _wpr_form_action_ and verify its value contains the <script> tag.

9. Alternative Approaches

  • Different action_type: If email doesn't work, try mailchimp, getresponse, or webhook.
  • Payload Variation: If <script> is blocked by a WAF (though unlikely in this isolated test), use:
    • <img src=x onerror=alert(1)>
    • "><details/open/ontoggle=alert(1)>
  • Targeting Templates: Instead of a Post ID, target an REA Template ID (post_type=wpr_templates).
Research Findings
Static analysis — not yet PoC-verified

Summary

Royal Addons for Elementor (<= 1.7.1056) is vulnerable to unauthenticated Stored Cross-Site Scripting via the 'status' parameter in the wpr_update_form_action_meta AJAX action. The vulnerability exists due to insufficient sanitization and escaping of stored metadata combined with a security nonce that is publicly exposed to all frontend visitors.

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>';

Exploit Outline

To exploit this vulnerability, an attacker first extracts the publicly leaked AJAX nonce from the 'WprConfig.nonce' variable on any frontend page where Royal Addons are loaded. Using this nonce, the attacker sends an unauthenticated POST request to /wp-admin/admin-ajax.php with the 'action' set to 'wpr_update_form_action_meta'. The payload includes a target 'post_id', an 'action_type' (e.g., 'email'), and a malicious script within the 'status' parameter. The injected script is saved to the post metadata and executes when an administrator navigates to the plugin's form submissions or settings page in the WordPress dashboard.

Check if your site is affected.

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