Advanced Order Export For WooCommerce <= 4.0.10 - Authenticated (Shop Manager+) SQL Injection via 'sort_direction' Parameter
Description
The Advanced Order Export For WooCommerce plugin for WordPress is vulnerable to generic SQL Injection via the 'sort_direction' parameter in all versions up to, and including, 4.0.10 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. The endpoint requires a valid woe_nonce and Shop Manager-level capabilities (view_woocommerce_reports or export_woocommerce_orders), and wp_magic_quotes protection is stripped via stripslashes_deep() before processing, allowing quote and backslash characters to survive intact into the SQL context.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=4.0.10What Changed in the Fix
Changes introduced in v4.1.0
Source Code
WordPress.org SVNThis research plan outlines the technical steps to verify the authenticated SQL Injection vulnerability (CVE-2026-11360) in the "Advanced Order Export For WooCommerce" plugin. ### 1. Vulnerability Summary * **Vulnerability:** Authenticated SQL Injection via the `sort_direction` parameter. * **L…
Show full research plan
This research plan outlines the technical steps to verify the authenticated SQL Injection vulnerability (CVE-2026-11360) in the "Advanced Order Export For WooCommerce" plugin.
1. Vulnerability Summary
- Vulnerability: Authenticated SQL Injection via the
sort_directionparameter. - Location: The vulnerability resides in the SQL generation logic within
WC_Order_Export_Data_Extractor(triggered by various AJAX methods inWC_Order_Export_Admin_Tab_Abstract_Ajax_Filters). - Cause: The plugin fails to validate or sanitize the
sort_directionparameter before concatenating it into anORDER BYclause. Although it usesstripslashes_deep()on the input, this actually removes WordPress's default magic quotes, allowing raw SQL metacharacters (like quotes and backslashes) to reach the database layer without proper preparation. - Impact: A Shop Manager or Administrator can execute arbitrary SQL queries to extract sensitive data from the WordPress database, including user password hashes and secret keys.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
order_exporter - Method (Parameter):
get_used_custom_order_meta(or any method callingsql_get_order_ids) - Vulnerable Parameter:
sort_direction - Authentication: Requires a user with
Shop Manager(or higher) capabilities. - Preconditions:
- WooCommerce must be active.
- The attacker must possess a valid
woe_nonce. - The attacker must have the
view_woocommerce_reportsorexport_woocommerce_orderscapability (default for Shop Managers).
3. Code Flow
- Entry Point: The AJAX action
order_exporteris registered in the plugin's administration classes. - AJAX Handling: Requests are routed to methods within the
WC_Order_Export_Admin_Tab_Abstract_Ajax_Filterstrait. For example,ajax_get_used_custom_order_meta(). - Nonce & Capability Check:
check_nonce()is called, verifying thewoe_nonceparameter. - Settings Processing:
WC_Order_Export_Manage::make_new_settings( $_POST )is called, which gathers settings from the request. - SQL Generation (Sink):
WC_Order_Export_Data_Extractor::sql_get_order_ids( $settings )is called. Inside this method, the code likely appends$settings['sort_direction']directly to the SQL query string used to fetch order IDs. - Stripping Slashes: The plugin applies
stripslashes_deep()to input, which allows characters like'to bypass WordPress's global sanitization and enter the SQL context.
4. Nonce Acquisition Strategy
The woe_nonce is localized into the admin page using wp_localize_script. It is stored in the global JavaScript object settings_form.
Acquisition Steps:
- Navigate to the plugin's settings page:
/wp-admin/admin.php?page=woo-order-export-lite. - Use the
browser_evaltool to extract the nonce:window.settings_form?.woe_nonce
5. Exploitation Strategy
We will use a time-based blind SQL injection payload to confirm the vulnerability.
Step-by-Step Plan:
- Login: Authenticate as a Shop Manager user.
- Nonce Capture: Navigate to the export settings page and extract
settings_form.woe_nonce. - Baseline Request: Send an AJAX request with
sort_direction=ASCand measure response time. - Injected Request: Send an AJAX request with a
SLEEP()payload in thesort_directionparameter.- Payload:
ASC, (SELECT 1 FROM (SELECT SLEEP(5))A)
- Payload:
- Execution: Use
http_request(Playwright) to send the POST request.
Request Details:
- Method:
POST - URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=order_exporter&method=get_used_custom_order_meta&woe_nonce=[NONCE]&sort_direction=ASC, (SELECT 1 FROM (SELECT SLEEP(5))A)
6. Test Data Setup
- WooCommerce: Ensure WooCommerce is installed and set up.
- Order: Create at least one test order so the query has data to process.
- User: Create a user with the
shop_managerrole.wp user create attacker attacker@example.com --role=shop_manager --user_pass=password
- Plugin Config: No special configuration is needed; the default settings are sufficient.
7. Expected Results
- Baseline: The response should be near-instant (e.g., < 200ms).
- Exploit: The response should be delayed by approximately 5 seconds.
- Response Body: The response will be a JSON object (e.g.,
["_billing_first_name", ...]) because the injection occurs in the query that fetches IDs for the meta-analysis.
8. Verification Steps
- Check the response time of the
http_requestcall. - To confirm data extraction, use a boolean-based payload to check the first character of the database version:
- Payload:
ASC, (SELECT 1 FROM (SELECT 1)A WHERE VERSION() LIKE '8%') - If the condition is true, the response is normal; if false, the ordering logic might change the response data order or cause a different behavior (if the subquery returns no rows).
- Payload:
9. Alternative Approaches
- Error-Based: If
WP_DEBUGis enabled, try inducing a database error usingupdatexml()orextractvalue()to leak data in the response body. - UNION-Based: If the
sort_directionparameter is injected into a context that allowsUNION(unlikely inORDER BYbut possible if the parameter is misused elsewhere), try to match column counts to reflect the admin password hash. - Other Methods: Try other
methodvalues in theorder_exporteraction, such asget_products_attributes_values, as seen inassets/js/filters.js.
Summary
Advanced Order Export For WooCommerce (up to 4.0.10) is vulnerable to authenticated SQL Injection via the 'sort_direction' parameter. This allows attackers with Shop Manager-level access to execute arbitrary SQL commands and extract sensitive data by injecting malicious payloads into ORDER BY clauses during export metadata extraction requests.
Vulnerable Code
// classes/admin/tabs/ajax/trait-wc-order-export-admin-tab-abstract-ajax-filters.php:84 public function ajax_get_used_custom_order_meta() { $this->check_nonce(); // Input settings are gathered from $_POST without validation for SQL keywords $settings = WC_Order_Export_Manage::make_new_settings( $_POST ); // The 'sort_direction' value in $settings is subsequently concatenated unvalidated into a SQL ORDER BY clause $sql = WC_Order_Export_Data_Extractor::sql_get_order_ids( $settings ); $ret = WC_Order_Export_Data_Extractor_UI::get_all_order_custom_meta_fields( $sql ); $this->print_escaped_json( $ret ); }
Security Fix
@@ -644,7 +644,7 @@ var repeat_options_html = {}; jQuery.each( localize_settings_form.repeats, function ( key, currentValue ) { - repeat_select.append( '<option value="' + key + '">' + currentValue + '</option>' ); + repeat_select.append( new Option(currentValue, key) ); repeat_options_html[key] = []; } ); ... (truncated)
Exploit Outline
The vulnerability is exploited by sending an authenticated POST request to the 'order_exporter' AJAX action. An attacker with Shop Manager privileges retrieves a valid 'woe_nonce' from the admin dashboard and then triggers one of several vulnerable AJAX methods, such as 'get_used_custom_order_meta'. By supplying a malicious SQL payload in the 'sort_direction' parameter (e.g., 'ASC, (SELECT SLEEP(5))'), the attacker can manipulate the query execution. This is possible because the plugin removes WordPress's default slash-escaping via stripslashes_deep() and lacks parameter binding or allow-listing for the sort order suffix.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.