[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fYUD3snHKibZhCSlr_EV7hj1ez9aX9ufdm7bvNT1pkQY":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-2373","royal-addons-for-elementor-addons-and-templates-kit-for-elementor-missing-authorization-to-unauthenticated-custom-post-t","Royal Addons for Elementor – Addons and Templates Kit for Elementor \u003C= 1.7.1049 - Missing Authorization to Unauthenticated Custom Post Type Contents Exposure","The Royal Addons for Elementor – Addons and Templates Kit for Elementor plugin for WordPress is vulnerable to Information Exposure in all versions up to, and including, 1.7.1049 via the get_main_query_args() function due to insufficient restrictions on which posts can be included. This makes it possible for unauthenticated attackers to extract contents of non-public custom post types, such as Contact Form 7 submissions or WooCommerce coupons.","royal-elementor-addons",null,"\u003C=1.7.1049","1.7.1050","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:L\u002FI:N\u002FA:N","Missing Authorization","2026-03-16 15:17:51","2026-03-17 03:36:25",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fc4192a7f-b962-46f9-a524-7271ed6f4917?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 analysis targets **CVE-2026-2373**, a missing authorization vulnerability in **Royal Addons for Elementor**. The vulnerability exists in the `get_main_query_args()` function (likely located in `WprAddons\\Classes\\Utilities`), which processes user-supplied query parameters for grid-based widgets without sufficient validation. This allows unauthenticated attackers to query and extract content from non-public Custom Post Types (CPTs) such as WooCommerce coupons or Contact Form 7 configurations.\n\n### 1. Vulnerability Summary\n*   **ID**: CVE-2026-2373\n*   **Vulnerability**: Missing Authorization \u002F Information Exposure\n*   **Affected Function**: `get_main_query_args()`\n*   **Sink**: `new \\WP_Query( $query_args )`\n*   **Root Cause**: The function accepts an array of settings (often from `$_POST['wpr_grid_query_args']`) and uses the `post_type` and `post_status` values directly in a WordPress query. There is no whitelist or authorization check to ensure the unauthenticated requester is allowed to view the requested post type.\n\n### 2. Attack Vector Analysis\n*   **Endpoint**: `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Action**: `wpr_get_grid_layout` (Unauthenticated via `wp_ajax_nopriv_wpr_get_grid_layout`)\n*   **Payload Parameter**: `wpr_grid_query_args` (JSON encoded or array)\n*   **Authentication**: None required (Unauthenticated).\n*   **Preconditions**: The Royal Addons for Elementor plugin must be active. A valid nonce is typically required for the AJAX action.\n\n### 3. Code Flow\n1.  **Entry Point**: An unauthenticated user sends a POST request to `admin-ajax.php` with `action=wpr_get_grid_layout`.\n2.  **AJAX Handler**: The plugin's AJAX handler (likely in a class handling Grids\u002FMagazine Grids) retrieves `$_POST['wpr_grid_query_args']`.\n3.  **Vulnerable Call**: The handler calls `WprAddons\\Classes\\Utilities::get_main_query_args( $settings )`, passing the user-controlled settings.\n4.  **Argument Construction**: `get_main_query_args()` constructs the `WP_Query` arguments using the `post_type` provided in the `$settings` array.\n5.  **Execution**: The handler executes `$query = new \\WP_Query( $args )`.\n6.  **Information Exposure**: The resulting posts (even if private or sensitive CPTs) are rendered and returned in the AJAX response.\n\n### 4. Nonce Acquisition Strategy\nRoyal Addons for Elementor typically localizes a configuration object named `WprConfig` which contains a nonce for AJAX requests.\n\n1.  **Requirement**: The nonce is usually enqueued on pages where a Royal Addons widget is present.\n2.  **Target Variable**: `window.WprConfig?.nonce`\n3.  **Procedure**:\n    *   Since the plugin is \"Elementor-first,\" creating a standard page with a Royal Addons widget is the most reliable way to trigger the script.\n    *   Use WP-CLI to create a page: `wp post create --post_type=page --post_status=publish --post_title=\"Exploit Page\" --post_content='\u003C!-- wp:elementor\u002Ftemplate -->'` (Or use an existing page if the plugin enqueues globally).\n    *   Navigate to the homepage or the created page using `browser_navigate`.\n    *   Extract the nonce: `browser_eval(\"window.WprConfig?.nonce\")`.\n    *   **Note**: If `WprConfig` is not found, check for `wprConfig` or `WprAddonsData`.\n\n### 5. Exploitation Strategy\nThe goal is to extract WooCommerce coupons (CPT: `shop_coupon`), which contains sensitive discount codes and logic.\n\n*   **Request URL**: `http:\u002F\u002F\u003Ctarget>\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method**: POST\n*   **Headers**: `Content-Type: application\u002Fx-www-form-urlencoded`\n*   **Body Parameters**:\n    *   `action`: `wpr_get_grid_layout`\n    *   `nonce`: `[EXTRACTED_NONCE]`\n    *   `wpr_grid_query_args`: A JSON-encoded string:\n        ```json\n        {\n          \"post_type\": \"shop_coupon\",\n          \"posts_per_page\": 10,\n          \"post_status\": \"publish\",\n          \"wpr_grid_template_id\": 0\n        }\n        ```\n    *   `wpr_grid_template_id`: `0` (or a valid template ID if required by the logic).\n\n### 6. Test Data Setup\nTo verify information exposure, sensitive data must exist in the database:\n\n1.  **Create WooCommerce Coupons** (Requires WooCommerce):\n    *   `wp eval \"wc_create_coupon(['code' => 'SECRET100', 'amount' => '100', 'discount_type' => 'fixed_cart']);\"`\n2.  **Create Private Content**:\n    *   `wp post create --post_type=post --post_title=\"Private Intel\" --post_content=\"The password is admin\" --post_status=private`\n3.  **Ensure Royal Addons Settings**: No specific settings are required, as the vulnerability is in the query builder utility.\n\n### 7. Expected Results\n*   **Successful Exploit**: The HTTP response (JSON or HTML) will contain the titles or content of the requested CPT. For `shop_coupon`, the response will likely show the coupon codes (e.g., \"SECRET100\") rendered within the grid item template.\n*   **Response Content**: Look for string patterns like `wpr-grid-item-title` containing the coupon codes or private post titles.\n\n### 8. Verification Steps\n1.  **Analyze HTTP Response**: Check the `body` of the `http_request` response for the sensitive string created in step 6 (e.g., \"SECRET100\").\n2.  **Compare with Public View**: Confirm the data is not visible on the standard frontend blog feed.\n3.  **Database Check**: Verify the post exists in the DB with the restricted status:\n    *   `wp db query \"SELECT post_title, post_type, post_status FROM wp_posts WHERE post_type='shop_coupon'\"`\n\n### 9. Alternative Approaches\n*   **Post Type: `wpcf7_contact_form`**: If Contact Form 7 is installed, use this `post_type` to extract form definitions which may contain email addresses or logic.\n*   **Post Type: `wp_block`**: Extract reusable blocks that might contain internal information.\n*   **Magazine Grid**: If `wpr_get_grid_layout` fails, try the Magazine Grid specific action: `action=wpr_get_magazine_grid_layout` with the same `wpr_grid_query_args` parameter.\n*   **Bypass Nonce**: Attempt the request without a nonce; if the plugin fails to call `check_ajax_referer` or `wp_verify_nonce` for the `nopriv` action, the exploit becomes even simpler.","The Royal Addons for Elementor plugin for WordPress (\u003C= 1.7.1049) is vulnerable to unauthenticated information exposure via the wpr_get_grid_layout AJAX action. This occurs because the get_main_query_args() function fails to validate or restrict the post_type and post_status parameters, allowing attackers to query and retrieve data from non-public custom post types like WooCommerce coupons or Contact Form 7 submissions.","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... (truncated)","To exploit this vulnerability, an unauthenticated attacker first obtains a valid AJAX nonce by visiting the site's frontend and extracting it from the WprConfig.nonce JavaScript object. The attacker then sends a POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the action parameter set to wpr_get_grid_layout. The payload must include a wpr_grid_query_args parameter containing a JSON-encoded object that specifies a non-public post_type (such as shop_coupon for WooCommerce or wpcf7_contact_form for Contact Form 7) and a post_status like publish or private. Because the server-side utility function get_main_query_args() fails to whitelist allowed post types, it will construct and execute a WP_Query based on the attacker's input and return the contents of those restricted posts in the response.","gemini-3-flash-preview","2026-04-18 03:13:09","2026-04-18 03:13:48",{"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"]