Premium Addons for Elementor <= 4.11.53 - Cross-Site Request Forgery via 'insert_inner_template'
Description
The Premium Addons for Elementor plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 4.11.53. This is due to missing nonce validation in the 'insert_inner_template' function. This makes it possible for unauthenticated attackers to create arbitrary Elementor templates via a forged request granted they can trick a site administrator or other user with the edit_posts capability 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
<=4.11.53Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-14163 (Premium Addons for Elementor CSRF) ## 1. Vulnerability Summary The **Premium Addons for Elementor** plugin (<= 4.11.53) is vulnerable to **Cross-Site Request Forgery (CSRF)**. The vulnerability exists because the function `insert_inner_template` (likely…
Show full research plan
Exploitation Research Plan: CVE-2025-14163 (Premium Addons for Elementor CSRF)
1. Vulnerability Summary
The Premium Addons for Elementor plugin (<= 4.11.53) is vulnerable to Cross-Site Request Forgery (CSRF). The vulnerability exists because the function insert_inner_template (likely registered as an AJAX handler) fails to implement WordPress nonce validation (check_ajax_referer or wp_verify_nonce). An attacker can trick an authenticated administrator into submitting a forged request that creates arbitrary Elementor templates, which could be used to inject malicious content or prepare for further attacks (like stored XSS via template injection).
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
insert_inner_template(inferred from the vulnerability description). - HTTP Method: POST
- Authentication Required: The request is executed in the context of an authenticated user (Administrator or Editor with
edit_postscapability). The attacker is unauthenticated. - Preconditions: The victim must be logged into WordPress and be tricked into visiting a malicious page or clicking a link that triggers the POST request.
3. Code Flow (Inferred)
- Entry Point: The plugin registers an AJAX action for
insert_inner_template.add_action( 'wp_ajax_insert_inner_template', array( $this, 'insert_inner_template' ) );
- Vulnerable Function: The
insert_inner_templatefunction is called. - Logic:
- The function likely checks for
current_user_can( 'edit_posts' )(or similar). - Missing Step: It does not call
check_ajax_referer()orwp_verify_nonce().
- The function likely checks for
- Sink: The function processes the
template_dataortemplate_contentfrom the$_POSTarray and callswp_insert_post()or uses Elementor'sTemplateLibrary\Source_Local::save_item()to save a new template to theelementor_librarypost type.
4. Nonce Acquisition Strategy
According to the vulnerability details, missing nonce validation is the core issue.
- Verification: During the exploitation phase, we will first attempt the request with a dummy nonce or no nonce at all.
- If the plugin did require a nonce for other related actions (but missed it here), the nonce would typically be localized under a key like
premium_addons_ajax?.nonceor similar. However, for this specific exploit, the strategy is to bypass nonce requirements entirely as they are absent in the vulnerable code path.
5. Exploitation Strategy
The goal is to demonstrate that an unauthenticated attacker can force an admin's browser to create a new Elementor template.
Step 1: Craft the Payload
The request requires parameters to define the template. Based on common Elementor Addon patterns, the parameters are likely:
action:insert_inner_templatetemplate_name:CSRF_Exploit_Templatetemplate_content: A JSON string representing Elementor widget data (e.g., a simple heading).template_type:sectionorpage.
Step 2: Trigger the Request (PoC)
Using the http_request tool to simulate the forged request coming from an authenticated admin's browser.
Request Details:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=insert_inner_template&template_name=VulnerableTemplate&template_content=[{"id":"1","elType":"section","settings":[],"elements":[{"id":"2","elType":"column","settings":{"_column_size":100},"elements":[{"id":"3","elType":"widget","settings":{"title":"Hacked by CSRF"},"widgetType":"heading"}]}]}]&template_type=section
6. Test Data Setup
- Plugin Installation: Ensure
premium-addons-for-elementorversion 4.11.53 is installed and active. - Elementor: Elementor (core) must be active as the plugin is an addon.
- User: An admin user session must be available for the
http_requesttool (using the provided authentication cookies).
7. Expected Results
- The server should return a successful JSON response, likely containing the ID of the newly created template (e.g.,
{"success": true, "data": {"template_id": 123}}). - A new post of type
elementor_librarywith the title "VulnerableTemplate" should exist in the database.
8. Verification Steps
After the http_request is sent, verify the creation of the template via WP-CLI:
# List Elementor templates and check for the one created via CSRF
wp post list --post_type=elementor_library --fields=ID,post_title,post_status
Check the content of the created template:
# Replace <ID> with the ID found in the previous step
wp post get <ID> --field=post_content
9. Alternative Approaches
If the template_content format is rejected:
- Check for simplified params: Try sending just
action=insert_inner_templateandtemplate_name=Testto see if a blank template is created. - Search for Template Import: If
insert_inner_templateis specifically for importing, it might expect a URL or a file upload. Check if the function uses$_FILESor aurlparameter. - Verify Capability: If the request returns a 403 or -1, double-check if the action name is correct by grepping the plugin source for
wp_ajax_insert_inner_template.
Summary
The Premium Addons for Elementor plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to 4.11.53 due to missing nonce validation in the 'insert_inner_template' AJAX handler. This allows unauthenticated attackers to trick an authorized user (like an administrator) into creating arbitrary Elementor templates by clicking a malicious link.
Vulnerable Code
// premium-addons-for-elementor/includes/class-premium-addons-ajax.php (approximate path) public function __construct() { add_action( 'wp_ajax_insert_inner_template', array( $this, 'insert_inner_template' ) ); } public function insert_inner_template() { if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error(); } // Missing check_ajax_referer() or wp_verify_nonce() call here $template_data = isset( $_POST['template_data'] ) ? $_POST['template_data'] : array(); // Logic continues to process and save template data to elementor_library post type }
Security Fix
@@ -10,6 +10,8 @@ public function insert_inner_template() { + check_ajax_referer( 'premium_addons_nonce', 'nonce' ); + if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error(); }
Exploit Outline
1. Target Endpoint: The attacker targets the WordPress AJAX endpoint at `/wp-admin/admin-ajax.php`. 2. Action: The request utilizes the `insert_inner_template` action registered by the plugin. 3. Authentication: The attacker requires no authentication but must trick a logged-in user with 'edit_posts' capabilities (like an Editor or Administrator) into executing the request. 4. Payload Shape: A POST request containing `action=insert_inner_template`, a `template_name`, and `template_content` (a JSON-encoded array representing Elementor widget structures). 5. Execution: The attacker hosts a malicious HTML page with a hidden form that auto-submits to the target site via the victim's browser session. Since no nonce is verified, the plugin accepts the request as legitimate and creates a new template in the Elementor library with the attacker's content.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.