Escape queries before passing to $wpdb methods

[MAILPOET-4219]
This commit is contained in:
Sam Najian
2022-03-31 16:54:51 +02:00
committed by Veljko V
parent a8d88beec9
commit a2ab1a3cfd
6 changed files with 85 additions and 89 deletions

View File

@@ -198,13 +198,13 @@ class FirstPurchase {
private function getGuestCustomerOrderCountByEmail($customerEmail) {
global $wpdb;
$count = $wpdb->get_var( "SELECT COUNT(*)
$count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*)
FROM $wpdb->posts as posts
LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
WHERE meta.meta_key = '_billing_email'
AND posts.post_type = 'shop_order'
AND meta_value = '" . WPFunctions::get()->escSql($customerEmail) . "'
" );
AND meta_value = %s
", $customerEmail));
return (int)$count;
}
}

View File

@@ -15,6 +15,7 @@ use MailPoet\Util\Notices\AfterMigrationNotice;
use MailPoet\Util\ProgressBar;
use MailPoet\WP\Functions as WPFunctions;
use MailPoetVendor\Idiorm\ORM;
use function WP_CLI\Utils\esc_like;
class MP2Migrator {
const IMPORT_TIMEOUT_IN_SECONDS = 7200; // Timeout = 2 hours
@@ -134,7 +135,7 @@ class MP2Migrator {
global $wpdb;
try {
$sql = "SHOW TABLES LIKE '{$table}'";
$sql = $wpdb->prepare("SHOW TABLES LIKE %s", $table);
$result = $wpdb->query($sql);
return !empty($result);
} catch (\Exception $e) {
@@ -369,14 +370,14 @@ class MP2Migrator {
global $wpdb;
$lastId = intval($this->settings->get('last_imported_list_id', 0));
$table = $this->mp2ListTable;
$sql = "
$table = esc_sql($this->mp2ListTable);
$sql = $wpdb->prepare("
SELECT l.list_id, l.name, l.description, l.is_enabled, l.created_at
FROM `$table` l
WHERE l.list_id > '$lastId'
WHERE l.list_id > %s
ORDER BY l.list_id
LIMIT $limit
";
LIMIT %d
", $lastId, $limit);
$lists = $wpdb->get_results($sql, ARRAY_A);
return $lists;
@@ -446,7 +447,7 @@ class MP2Migrator {
global $wpdb;
$customFields = [];
$table = $this->mp2CustomFieldTable;
$table = esc_sql($this->mp2CustomFieldTable);
$sql = "
SELECT cf.id, cf.name, cf.type, cf.required, cf.settings
FROM `$table` cf
@@ -606,14 +607,14 @@ class MP2Migrator {
private function getUsers($limit) {
global $wpdb;
$lastId = intval($this->settings->get('last_imported_user_id', 0));
$table = $this->mp2UserTable;
$sql = "
$table = esc_sql($this->mp2UserTable);
$sql = $wpdb->prepare("
SELECT u.*
FROM `$table` u
WHERE u.user_id > '$lastId'
WHERE u.user_id > %d
ORDER BY u.user_id
LIMIT $limit
";
LIMIT %d
", $lastId, $limit);
$users = $wpdb->get_results($sql, ARRAY_A);
return $users;
@@ -703,12 +704,12 @@ class MP2Migrator {
private function getUserLists($userId) {
global $wpdb;
$table = $this->mp2UserListTable;
$sql = "
$table = esc_sql($this->mp2UserListTable);
$sql = $wpdb->prepare("
SELECT ul.list_id, ul.sub_date, ul.unsub_date
FROM `$table` ul
WHERE ul.user_id = '$userId'
";
WHERE ul.user_id = %s
", $userId);
$userLists = $wpdb->get_results($sql, ARRAY_A);
return $userLists;
@@ -853,14 +854,14 @@ class MP2Migrator {
global $wpdb;
$lastId = intval($this->settings->get('last_imported_form_id', 0));
$table = $this->mp2FormTable;
$sql = "
$table = esc_sql($this->mp2FormTable);
$sql = $wpdb->prepare("
SELECT f.*
FROM `$table` f
WHERE f.form_id > '$lastId'
WHERE f.form_id > %s
ORDER BY f.form_id
LIMIT $limit
";
LIMIT %d
", $lastId, $limit);
$forms = $wpdb->get_results($sql, ARRAY_A);
return $forms;
@@ -1117,12 +1118,12 @@ class MP2Migrator {
global $wpdb;
$email = [];
$table = $this->mp2EmailTable;
$sql = "
$table = esc_sql($this->mp2EmailTable);
$sql = $wpdb->prepare("
SELECT e.*
FROM `$table` e
WHERE e.email_id = '$emailId'
";
WHERE e.email_id = %s
", $emailId);
$email = $wpdb->get_row($sql, ARRAY_A);
return $email;

View File

@@ -100,7 +100,7 @@ class Migrator {
$_this = $this;
$dropTable = function($model) use($wpdb, $_this) {
$table = $_this->prefix . $model;
$table = esc_sql($_this->prefix . $model);
$wpdb->query("DROP TABLE {$table}");
};
@@ -642,8 +642,9 @@ class Migrator {
if (version_compare((string)$this->settings->get('db_version', '3.47.6'), '3.47.6', '>')) {
return false;
}
$table = esc_sql("{$this->prefix}statistics_unsubscribes");
$query = "
ALTER TABLE `{$this->prefix}statistics_unsubscribes`
ALTER TABLE `{$table}`
CHANGE `newsletter_id` `newsletter_id` int(11) unsigned NULL,
CHANGE `queue_id` `queue_id` int(11) unsigned NULL;
";
@@ -665,7 +666,7 @@ class Migrator {
}
global $wpdb;
$scheduledTasksSubscribersTable = "{$this->prefix}scheduled_task_subscribers";
$scheduledTasksSubscribersTable = esc_sql("{$this->prefix}scheduled_task_subscribers");
// Remove default CURRENT_TIMESTAMP from created_at
$updateCreatedAtQuery = "
ALTER TABLE `$scheduledTasksSubscribersTable`
@@ -674,11 +675,11 @@ class Migrator {
$wpdb->query($updateCreatedAtQuery);
// Add updated_at column in case it doesn't exist
$updatedAtColumnExists = $wpdb->get_results("
$updatedAtColumnExists = $wpdb->get_results($wpdb->prepare("
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = '$scheduledTasksSubscribersTable' AND column_name = 'updated_at';
");
WHERE table_name = %s AND column_name = 'updated_at';
", $scheduledTasksSubscribersTable));
if (empty($updatedAtColumnExists)) {
$addUpdatedAtQuery = "
ALTER TABLE `$scheduledTasksSubscribersTable`
@@ -698,17 +699,17 @@ class Migrator {
$dbName = Env::$dbName;
$statisticsTables = [
"{$this->prefix}statistics_clicks",
"{$this->prefix}statistics_opens",
esc_sql("{$this->prefix}statistics_clicks"),
esc_sql("{$this->prefix}statistics_opens"),
];
foreach ($statisticsTables as $statisticsTable) {
$oldStatisticsIndexExists = $wpdb->get_results("
$oldStatisticsIndexExists = $wpdb->get_results($wpdb->prepare("
SELECT DISTINCT INDEX_NAME
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = '{$dbName}'
AND TABLE_NAME = '$statisticsTable'
WHERE TABLE_SCHEMA = %s
AND TABLE_NAME = %s
AND INDEX_NAME='newsletter_id_subscriber_id'
");
", $dbName, $statisticsTable));
if (!empty($oldStatisticsIndexExists)) {
$dropIndexQuery = "
ALTER TABLE `{$statisticsTable}`
@@ -728,7 +729,7 @@ class Migrator {
return false;
}
$dynamicSegmentFiltersTable = "{$this->prefix}dynamic_segment_filters";
$dynamicSegmentFiltersTable = esc_sql("{$this->prefix}dynamic_segment_filters");
$dynamicSegmentFilters = $wpdb->get_results("
SELECT id, filter_data, filter_type, `action`
FROM {$dynamicSegmentFiltersTable}
@@ -758,7 +759,7 @@ class Migrator {
return false;
}
$dynamicSegmentFiltersTable = "{$this->prefix}dynamic_segment_filters";
$dynamicSegmentFiltersTable = esc_sql("{$this->prefix}dynamic_segment_filters");
$filterType = DynamicSegmentFilterData::TYPE_WOOCOMMERCE;
$action = WooCommerceProduct::ACTION_PRODUCT;
$dynamicSegmentFilters = $wpdb->get_results("
@@ -798,15 +799,15 @@ class Migrator {
return false;
}
$dynamicSegmentFiltersTable = "{$this->prefix}dynamic_segment_filters";
$dynamicSegmentFiltersTable = esc_sql("{$this->prefix}dynamic_segment_filters");
$filterType = DynamicSegmentFilterData::TYPE_WOOCOMMERCE;
$action = WooCommerceCategory::ACTION_CATEGORY;
$dynamicSegmentFilters = $wpdb->get_results("
$dynamicSegmentFilters = $wpdb->get_results($wpdb->prepare("
SELECT `id`, `filter_data`, `filter_type`, `action`
FROM {$dynamicSegmentFiltersTable}
WHERE `filter_type` = '{$filterType}'
AND `action` = '{$action}'
", ARRAY_A);
WHERE `filter_type` = %s
AND `action` = %s
", $filterType, $action), ARRAY_A);
foreach ($dynamicSegmentFilters as $dynamicSegmentFilter) {
$filterData = unserialize($dynamicSegmentFilter['filter_data']);
@@ -838,15 +839,15 @@ class Migrator {
return false;
}
$dynamicSegmentFiltersTable = "{$this->prefix}dynamic_segment_filters";
$dynamicSegmentFiltersTable = esc_sql("{$this->prefix}dynamic_segment_filters");
$filterType = DynamicSegmentFilterData::TYPE_WOOCOMMERCE_SUBSCRIPTION;
$action = WooCommerceSubscription::ACTION_HAS_ACTIVE;
$dynamicSegmentFilters = $wpdb->get_results("
$dynamicSegmentFilters = $wpdb->get_results($wpdb->prepare("
SELECT `id`, `filter_data`, `filter_type`, `action`
FROM {$dynamicSegmentFiltersTable}
WHERE `filter_type` = '{$filterType}'
AND `action` = '{$action}'
", ARRAY_A);
WHERE `filter_type` = %s
AND `action` = %s
", $filterType, $action), ARRAY_A);
foreach ($dynamicSegmentFilters as $dynamicSegmentFilter) {
$filterData = unserialize($dynamicSegmentFilter['filter_data']);
@@ -877,7 +878,7 @@ class Migrator {
return false;
}
$dynamicSegmentFiltersTable = "{$this->prefix}dynamic_segment_filters";
$dynamicSegmentFiltersTable = esc_sql("{$this->prefix}dynamic_segment_filters");
$filterType = DynamicSegmentFilterData::TYPE_EMAIL;
$dynamicSegmentFilters = $wpdb->get_results("
SELECT `id`, `filter_data`, `filter_type`, `action`

View File

@@ -530,17 +530,17 @@ class Populator {
}
}
private function rowExists($table, $columns) {
private function rowExists(string $tableName, array $columns): bool {
global $wpdb;
$conditions = array_map(function($key) {
return $key . '=%s';
$conditions = array_map(function($key) use ($columns) {
return "$key='{$columns[$key]}'";
}, array_keys($columns));
return $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM $table WHERE " . implode(' AND ', $conditions),
array_values($columns)
)) > 0;
$table = esc_sql($tableName);
return $wpdb->get_var(
"SELECT COUNT(*) FROM $table WHERE " . implode(' AND ', $conditions)
) > 0;
}
private function insertRow($table, $row) {
@@ -575,7 +575,6 @@ class Populator {
$conditions = implode(' AND ', $conditions);
$sql = "DELETE FROM `$table` WHERE $conditions";
return $wpdb->query(
$wpdb->prepare(
"DELETE t1 FROM $table t1, $table t2 WHERE t1.id < t2.id AND $conditions",
@@ -614,8 +613,7 @@ class Populator {
}
$tables = [ScheduledTask::$_table, SendingQueue::$_table];
foreach ($tables as $table) {
$query = "UPDATE `%s` SET meta = NULL WHERE meta = 'null'";
$wpdb->query(sprintf($query, $table));
$wpdb->query("UPDATE `$table` SET meta = NULL WHERE meta = 'null'");
}
return true;
}
@@ -652,12 +650,12 @@ class Populator {
if (version_compare((string)$this->settings->get('db_version', '3.42.1'), '3.42.0', '>')) {
return false;
}
$query = "UPDATE `%s` SET last_subscribed_at = GREATEST(COALESCE(confirmed_at, 0), COALESCE(created_at, 0)) WHERE status != '%s' AND last_subscribed_at IS NULL;";
$wpdb->query(sprintf(
$query,
Subscriber::$_table,
$table = esc_sql(Subscriber::$_table);
$query = $wpdb->prepare(
"UPDATE `{$table}` SET last_subscribed_at = GREATEST(COALESCE(confirmed_at, 0), COALESCE(created_at, 0)) WHERE status != %s AND last_subscribed_at IS NULL;",
Subscriber::STATUS_UNCONFIRMED
));
);
$wpdb->query($query);
return true;
}
@@ -886,19 +884,14 @@ class Populator {
)
);
if ($premiumTableExists) {
$table = esc_sql(Newsletter::$_table);
$query = "
UPDATE
`%s` as n
JOIN %s as ped ON n.id=ped.newsletter_id
`{$table}` as n
JOIN `$premiumTableName` as ped ON n.id=ped.newsletter_id
SET n.ga_campaign = ped.ga_campaign
";
$wpdb->query(
sprintf(
$query,
Newsletter::$_table,
$premiumTableName
)
);
$wpdb->query($query);
}
return true;
}

View File

@@ -85,7 +85,7 @@ class Migration extends SimpleWorker {
private function checkUnmigratedColumnsExist() {
global $wpdb;
$existingColumns = $wpdb->get_col('DESC ' . SendingQueueModel::$_table);
$existingColumns = $wpdb->get_col('DESC ' . esc_sql(SendingQueueModel::$_table));
return in_array('type', $existingColumns);
}
@@ -145,12 +145,13 @@ class Migration extends SimpleWorker {
));
// link the queue with the task via task_id
$newTaskId = $wpdb->insert_id; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
$wpdb->query(sprintf(
'UPDATE %1$s SET `task_id` = %2$s WHERE `id` = %3$s',
MP_SENDING_QUEUES_TABLE,
$table = esc_sql(MP_SENDING_QUEUES_TABLE);
$query = $wpdb->prepare(
"UPDATE `$table` SET `task_id` = %s WHERE `id` = %s",
$newTaskId,
$queue['id']
));
);
$wpdb->query($query);
}
}
}
@@ -195,10 +196,10 @@ class Migration extends SimpleWorker {
$migratedUnprocessedCount = ScheduledTaskSubscriber::getUnprocessedCount($taskId);
$migratedProcessedCount = ScheduledTaskSubscriber::getProcessedCount($taskId);
$subscribers = $wpdb->get_var(sprintf(
'SELECT `subscribers` FROM %1$s WHERE `task_id` = %2$d ' .
'AND (`count_processed` > %3$d OR `count_to_process` > %4$d)',
MP_SENDING_QUEUES_TABLE,
$table = MP_SENDING_QUEUES_TABLE;
$subscribers = $wpdb->get_var($wpdb->prepare(
"SELECT `subscribers` FROM `$table` WHERE `task_id` = %d
AND (`count_processed` > %d OR `count_to_process` > %d)",
$taskId,
$migratedUnprocessedCount,
$migratedProcessedCount

View File

@@ -63,10 +63,10 @@ class Helper {
public function getOrdersCountCreatedBefore($dateTime) {
global $wpdb;
$result = $wpdb->get_var("
$result = $wpdb->get_var($wpdb->prepare("
SELECT DISTINCT count(p.ID) FROM {$wpdb->prefix}posts as p
WHERE p.post_type = 'shop_order' AND p.post_date < '{$dateTime}'
");
WHERE p.post_type = 'shop_order' AND p.post_date < %s
"), $dateTime);
return (int)$result;
}