Commit 998bdd5d330 for woocommerce

commit 998bdd5d33081032df057c6ffaca1456b13c50ee
Author: Liam Sarsfield <43409125+LiamSarsfield@users.noreply.github.com>
Date:   Mon Aug 10 14:06:01 2026 +0100

    Fix SQL injection via woocommerce_date_type in Analytics reports (#67546)

    Co-authored-by: Mike Jolley <mike.jolley@me.com>

diff --git a/plugins/woocommerce/changelog/fix-analytics-date-type-allowlist b/plugins/woocommerce/changelog/fix-analytics-date-type-allowlist
new file mode 100644
index 00000000000..a204b87f3a9
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-analytics-date-type-allowlist
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Validate the Analytics order date type option against known columns.
diff --git a/plugins/woocommerce/src/Admin/API/Reports/DataStore.php b/plugins/woocommerce/src/Admin/API/Reports/DataStore.php
index 4b5a3d3120d..8f1175abd2a 100644
--- a/plugins/woocommerce/src/Admin/API/Reports/DataStore.php
+++ b/plugins/woocommerce/src/Admin/API/Reports/DataStore.php
@@ -98,6 +98,18 @@ class DataStore extends SqlQuery implements DataStoreInterface {
 	 */
 	protected $date_column_name = 'date_created';

+	/**
+	 * Allow-list a date column name before it is interpolated into SQL.
+	 *
+	 * @param string $column   Requested date column name.
+	 * @param string $fallback Column to use when the requested one is not allowed.
+	 * @return string
+	 */
+	protected function sanitize_date_column_name( $column, $fallback = 'date_created' ) {
+		$allowed = array( 'date_created', 'date_created_gmt', 'date_paid', 'date_completed' );
+		return in_array( $column, $allowed, true ) ? $column : $fallback;
+	}
+
 	/**
 	 * Mapping columns to data type to return correct response types.
 	 *
diff --git a/plugins/woocommerce/src/Admin/API/Reports/Orders/DataStore.php b/plugins/woocommerce/src/Admin/API/Reports/Orders/DataStore.php
index cd2c04c87b9..14bcd62f20e 100644
--- a/plugins/woocommerce/src/Admin/API/Reports/Orders/DataStore.php
+++ b/plugins/woocommerce/src/Admin/API/Reports/Orders/DataStore.php
@@ -32,7 +32,7 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
 	 * @override ReportsDataStore::__construct()
 	 */
 	public function __construct() {
-		$this->date_column_name = get_option( 'woocommerce_date_type', 'date_paid' );
+		$this->date_column_name = $this->sanitize_date_column_name( get_option( 'woocommerce_date_type' ), 'date_paid' );
 		parent::__construct();
 	}

diff --git a/plugins/woocommerce/src/Admin/API/Reports/Orders/Stats/DataStore.php b/plugins/woocommerce/src/Admin/API/Reports/Orders/Stats/DataStore.php
index b5aa835028d..26788359d13 100644
--- a/plugins/woocommerce/src/Admin/API/Reports/Orders/Stats/DataStore.php
+++ b/plugins/woocommerce/src/Admin/API/Reports/Orders/Stats/DataStore.php
@@ -101,7 +101,7 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
 	 * @override ReportsDataStore::__construct()
 	 */
 	public function __construct() {
-		$this->date_column_name = get_option( 'woocommerce_date_type', 'date_paid' );
+		$this->date_column_name = $this->sanitize_date_column_name( get_option( 'woocommerce_date_type' ), 'date_paid' );
 		parent::__construct();
 	}

@@ -342,7 +342,7 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
 		$table_name = self::get_db_table_name();

 		if ( isset( $query_args['date_type'] ) ) {
-			$this->date_column_name = $query_args['date_type'];
+			$this->date_column_name = $this->sanitize_date_column_name( $query_args['date_type'] );
 		}

 		$this->initialize_queries();