Element Pack Elementor Addons <= 8.3.13 - Cross-Site Request Forgery
Description
The Element Pack Addons for Elementor plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 8.3.13. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action granted they can trick a site administrator into performing an action such as clicking on a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:NTechnical Details
<=8.3.13Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-31413 (CSRF in Element Pack Elementor Addons) ## 1. Vulnerability Summary The **Element Pack Elementor Addons** plugin (<= 8.3.13) contains a Cross-Site Request Forgery (CSRF) vulnerability. This issue arises from a failure to correctly implement or verify Wor…
Show full research plan
Exploitation Research Plan: CVE-2025-31413 (CSRF in Element Pack Elementor Addons)
1. Vulnerability Summary
The Element Pack Elementor Addons plugin (<= 8.3.13) contains a Cross-Site Request Forgery (CSRF) vulnerability. This issue arises from a failure to correctly implement or verify WordPress nonces on administrative AJAX actions. Specifically, certain handlers intended for managing plugin settings or module statuses either omit the check_ajax_referer call entirely or use it with the die parameter set to false without subsequently checking the return value. This allows an unauthenticated attacker to perform sensitive configuration changes by tricking a logged-in administrator into visiting a malicious link or form.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Vulnerable Action:
element_pack_settings_saveorep_module_toggle(inferred; based on common patterns in this plugin's administrative interface). - HTTP Method:
POST - Payload Parameter:
action,settings_data(or individual setting keys), and potentially a dummy or missingsecurity/nonceparameter. - Authentication Level: Requires an active Administrator session (exploited via CSRF).
- Preconditions: The victim must be logged in as an administrator.
3. Code Flow
- The plugin registers AJAX handlers during
initoradmin_inithooks, typically within theincludes/class-element-pack-admin.phpor similar administrative controller. - An action like
wp_ajax_element_pack_settings_saveis mapped to a callback function (e.g.,save_settings_callback). - Inside the callback, the code likely checks for
current_user_can('manage_options')but fails to strictly validate a nonce usingcheck_ajax_referer('element-pack-settings', 'security'). - If
check_ajax_refereris used with$die = false, and the return value is ignored, execution continues to the sink. - Sink: The user-supplied data in
$_POSTis passed toupdate_option()orupdate_site_option(), allowing modification of plugin behaviors (e.g., enabling/disabling security features, changing API keys, or modifying layout settings).
4. Nonce Acquisition Strategy
If the plugin attempts "incorrect" nonce validation (e.g., using a mismatched action string or an improperly localized nonce), we need to identify the localization key.
- Identify Script Localization: Search the source for
wp_localize_script. Look for the variable name used to pass data to the admin dashboard.- Likely Variable:
element_pack_config(inferred). - Likely Key:
ajax_nonceornonce(inferred).
- Likely Variable:
- Create Trigger Content: Element Pack nonces are often only loaded on the plugin's settings page. To extract one:
wp post create --post_type=page --post_status=publish --post_title="EP Admin" --post_content='[element-pack-some-widget]'(Note: In CSRF, the admin's browser already has the nonce if they are on the settings page, but for PoC verification, we navigate there).
- Extraction via Browser:
// Using browser_eval to find the localized nonce const nonce = window.element_pack_config?.ajax_nonce || window.element_pack_admin_config?.security; - Bypass Analysis: If
check_ajax_refereris called with$die = falseand the result is not checked, the strategy is simply to provide any value or omit the parameter.
5. Exploitation Strategy
We will simulate a CSRF attack by performing a POST request from the "attacker" context while the agent holds admin session cookies.
Step 1: Identify the vulnerable action
The agent should first search for wp_ajax_ registrations in the plugin directory:grep -rn "wp_ajax_" .
Step 2: Construct the CSRF Payload
Assuming the vulnerable action is element_pack_save_settings:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Content-Type:
application/x-www-form-urlencoded - Body:
Note: We test withaction=element_pack_save_settings&security=WRONG_NONCE&settings[some_critical_feature]=offWRONG_NONCEto confirm the "incorrect validation" aspect.
Step 3: Execution
Use http_request with the admin cookies to send the payload.
6. Test Data Setup
- Plugin Activation: Ensure
bdthemes-element-pack-liteis installed and active. - Initial State: Check the current value of a target option.
wp option get element_pack_active_modules
- Admin Context: The agent must be authenticated as an admin (already standard in the test environment).
7. Expected Results
- HTTP Response: A
200 OKresponse, often containing{"success": true}or1. - Vulnerability Confirmation: The request succeeds even if the
securityornonceparameter is invalid, expired, or missing. - Impact: The targeted WordPress option (
element_pack_*) is updated in the database.
8. Verification Steps
After sending the HTTP request, verify the change using WP-CLI:
# Verify the option was changed
wp option get element_pack_active_modules
# Or check for a specific setting modified in the payload
wp option get bd_element_pack_settings
9. Alternative Approaches
- Mismatched Actions: If a nonce is checked, compare the action string in
wp_create_nonce(localized) vscheck_ajax_referer(in the handler). If they differ (e.g.,element-pack-noncevselement-pack-security), the check will fail for the intended use but might accept a default nonce (-1) or a nonce from a different part of the plugin. - Admin Post Hook: Check if the settings are saved via
admin-post.phpinstead of AJAX. Look foradd_action('admin_post_...'). These are frequently missing CSRF protection compared to AJAX handlers. - Grep for Weak Validation:
grep -rn "check_ajax_referer.*false" .grep -rn "wp_verify_nonce" . | grep -v "if"
Summary
The Element Pack Elementor Addons plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) due to a lack of nonce validation on administrative AJAX actions. This allows an unauthenticated attacker to modify plugin settings or toggle modules by tricking a logged-in administrator into interacting with a malicious link or page.
Vulnerable Code
// Inferred from research plan // File: includes/admin/class-element-pack-admin.php add_action('wp_ajax_element_pack_settings_save', 'element_pack_settings_save'); function element_pack_settings_save() { // Only capability check is performed, missing nonce validation if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'Permission denied' ); } if ( isset( $_POST['settings_data'] ) ) { update_option( 'element_pack_settings', $_POST['settings_data'] ); } wp_send_json_success(); }
Security Fix
@@ -102,6 +102,8 @@ function element_pack_settings_save() { + check_ajax_referer( 'element-pack-settings-nonce', 'security' ); + if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'Permission denied' ); }
Exploit Outline
The attacker crafts a malicious web page containing an automated HTML form or JavaScript-based POST request targeting the WordPress AJAX endpoint (/wp-admin/admin-ajax.php). The request includes the 'action' parameter set to a vulnerable handler like 'element_pack_settings_save' along with malicious 'settings_data' to reconfigure the plugin. If a logged-in administrator visits the page, their browser automatically sends the request with their session cookies. Because the plugin does not verify a unique nonce, the server accepts the unauthorized command.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.