Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/affiliate-toolkit-starter/affiliate-toolkit.php
+++ b/affiliate-toolkit-starter/affiliate-toolkit.php
@@ -2,7 +2,7 @@
/*** Plugin Name: affiliate-toolkit – Multi-Network Affiliate & Amazon Product Display
* Plugin URI: https://www.affiliate-toolkit.com
* Description: Display products from Amazon, AWIN, CJ, eBay and 10+ affiliate networks with beautiful product boxes, comparison tables, and automatic price updates.
- * Version: 3.8.8
+ * Version: 3.8.9
* Requires PHP: 8.2
* Author: SERVIT Software Solutions
* Author URI: https://servit.dev
@@ -12,7 +12,7 @@
* License: GPL2
*/
-define( 'ATKP_UPDATE_VERSION', '3.8.8' );
+define( 'ATKP_UPDATE_VERSION', '3.8.9' );
define( 'ATKP_UPDATE_ITEM_ID', '7680' );
if ( ! defined( 'ABSPATH' ) ) {
--- a/affiliate-toolkit-starter/includes/database/atkp_queuetable_helper.php
+++ b/affiliate-toolkit-starter/includes/database/atkp_queuetable_helper.php
@@ -335,9 +335,10 @@
$sql = "SELECT * FROM {$tablename}";
- if ( ! empty( $orderby ) ) {
- $sql .= ' ORDER BY ' . esc_sql( $orderby );
- $sql .= ! empty( $order ) ? ' ' . esc_sql( $order ) : ' ASC';
+ $allowed_orderby = array( 'id', 'title', 'createdon', 'status' );
+ if ( ! empty( $orderby ) && in_array( $orderby, $allowed_orderby, true ) ) {
+ $order = in_array( strtolower( $order ), array( 'asc', 'desc' ), true ) ? $order : 'ASC';
+ $sql .= ' ORDER BY ' . $orderby . ' ' . $order;
}
$per_page = intval( $per_page );
@@ -359,11 +360,6 @@
$sql = "SELECT * FROM {$tablename} where createdon >= %s and status in ('error')";
- if ( ! empty( $orderby ) ) {
- $sql .= ' ORDER BY ' . esc_sql( $orderby );
- $sql .= ! empty( $order ) ? ' ' . esc_sql( $order ) : ' ASC';
- }
-
$limit = intval( $limit );
$sql .= " LIMIT " . $limit;
@@ -394,9 +390,10 @@
$sql .= ' and status in ("error", "not_processed")';
}
- if ( ! empty( $orderby ) ) {
- $sql .= ' ORDER BY ' . esc_sql( $orderby );
- $sql .= ! empty( $order ) ? ' ' . esc_sql( $order ) : ' ASC';
+ $allowed_orderby = array( 'id', 'title', 'createdon', 'status' );
+ if ( ! empty( $orderby ) && in_array( $orderby, $allowed_orderby, true ) ) {
+ $order = in_array( strtolower( $order ), array( 'asc', 'desc' ), true ) ? $order : 'ASC';
+ $sql .= ' ORDER BY ' . $orderby . ' ' . $order;
}
$sql .= $wpdb->prepare( " LIMIT %d", $per_page );
--- a/affiliate-toolkit-starter/includes/models/atkp_template.php
+++ b/affiliate-toolkit-starter/includes/models/atkp_template.php
@@ -143,16 +143,20 @@
$sql = "SELECT * FROM {$wpdb->posts} where post_type='atkp_template' and post_status in ('draft', 'publish')";
- if ( ! empty( $orderby ) ) {
- $sql .= ' ORDER BY ' . esc_sql( $orderby );
- $sql .= ! empty( $order ) ? ' ' . esc_sql( $order ) : ' ASC';
+ $allowed_orderby = array( 'id', 'post_title', 'post_date', 'post_status' );
+ if ( ! empty( $orderby ) && in_array( $orderby, $allowed_orderby, true ) ) {
+ $order = in_array( strtolower( $order ), array( 'asc', 'desc' ), true ) ? $order : 'ASC';
+ $sql .= ' ORDER BY ' . $orderby . ' ' . $order;
}
- $sql .= " LIMIT $per_page";
- $sql .= ' OFFSET ' . ( $page_number - 1 ) * $per_page;
+ $per_page = intval( $per_page );
+ $page_number = intval( $page_number );
+ $offset = ( $page_number - 1 ) * $per_page;
+ $sql .= $wpdb->prepare( " LIMIT %d", $per_page );
+ $sql .= $wpdb->prepare( " OFFSET %d", $offset );
- // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Admin template listing, values sanitized via esc_sql() and cast to int.
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- Admin template listing, orderby/order whitelisted, limit/offset prepared.
$result = $wpdb->get_results( $sql, 'ARRAY_A' );
return $result;
--- a/affiliate-toolkit-starter/includes/pages/atkp_queue_entry_table.php
+++ b/affiliate-toolkit-starter/includes/pages/atkp_queue_entry_table.php
@@ -262,9 +262,12 @@
] );
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- WP_List_Table sorting parameters.
- $orderby = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'id';
+ $orderby_raw = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'id';
+ $allowed_orderby = array( 'id', 'title', 'createdon', 'status' );
+ $orderby = in_array( $orderby_raw, $allowed_orderby, true ) ? $orderby_raw : 'id';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
- $order = isset( $_REQUEST['order'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : 'asc';
+ $order_raw = isset( $_REQUEST['order'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : 'asc';
+ $order = in_array( strtolower( $order_raw ), array( 'asc', 'desc' ), true ) ? $order_raw : 'asc';
$this->items = atkp_queue_entry::get_list( self::$queue->id, $filter, $per_page, $current_page, $orderby, $order );
}
--- a/affiliate-toolkit-starter/includes/pages/atkp_queue_table.php
+++ b/affiliate-toolkit-starter/includes/pages/atkp_queue_table.php
@@ -270,9 +270,12 @@
] );
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- WP_List_Table sorting parameters.
- $orderby = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'id';
+ $orderby_raw = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'id';
+ $allowed_orderby = array( 'id', 'title', 'createdon', 'status' );
+ $orderby = in_array( $orderby_raw, $allowed_orderby, true ) ? $orderby_raw : 'id';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
- $order = isset( $_REQUEST['order'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : 'desc';
+ $order_raw = isset( $_REQUEST['order'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : 'desc';
+ $order = in_array( strtolower( $order_raw ), array( 'asc', 'desc' ), true ) ? $order_raw : 'desc';
$this->items = atkp_queue::get_list( $per_page, $current_page, $orderby, $order );
}
--- a/affiliate-toolkit-starter/includes/pages/atkp_template_table.php
+++ b/affiliate-toolkit-starter/includes/pages/atkp_template_table.php
@@ -276,9 +276,12 @@
] );
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- WP_List_Table sorting parameters.
- $orderby = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'id';
+ $orderby_raw = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'id';
+ $allowed_orderby = array( 'id', 'post_title', 'post_date', 'post_status' );
+ $orderby = in_array( $orderby_raw, $allowed_orderby, true ) ? $orderby_raw : 'id';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
- $order = isset( $_REQUEST['order'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : 'desc';
+ $order_raw = isset( $_REQUEST['order'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ) : 'desc';
+ $order = in_array( strtolower( $order_raw ), array( 'asc', 'desc' ), true ) ? $order_raw : 'desc';
if ( $view == 'system' ) {
$this->items = atkp_template::get_system_list( $per_page, $current_page, $orderby, $order );