From 7603eb1af469119db267b858c89514d041ec73ba Mon Sep 17 00:00:00 2001 From: CiviCRM Date: Fri, 1 Sep 2023 22:13:38 -0700 Subject: [PATCH] CIVI-SA-2023-09 - SQLI via API getFields --- CRM/Contact/BAO/Contact.php | 4 +++- CRM/Core/OptionGroup.php | 7 +++++-- tests/phpunit/CRM/Core/OptionGroupTest.php | 21 +++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CRM/Contact/BAO/Contact.php b/CRM/Contact/BAO/Contact.php index a925762dd4..2c21311b9d 100644 --- a/CRM/Contact/BAO/Contact.php +++ b/CRM/Contact/BAO/Contact.php @@ -3311,7 +3311,9 @@ LEFT JOIN civicrm_address ON ( civicrm_address.contact_id = civicrm_contact.id ) switch ($fieldName) { case 'contact_sub_type': if (!empty($props['contact_type'])) { - $params['condition'] = "parent_id = (SELECT id FROM civicrm_contact_type WHERE name='{$props['contact_type']}')"; + $params['condition'] = CRM_Core_DAO::composeQuery('parent_id = (SELECT id FROM civicrm_contact_type WHERE name = %1)', [ + 1 => [$props['contact_type'], 'String'], + ]); } break; diff --git a/CRM/Core/OptionGroup.php b/CRM/Core/OptionGroup.php index dac6a726ae..f6a2a0d866 100644 --- a/CRM/Core/OptionGroup.php +++ b/CRM/Core/OptionGroup.php @@ -160,9 +160,12 @@ WHERE v.option_group_id = g.id $query .= $condition; } - $query .= " ORDER BY v.{$orderBy}"; + $query .= " ORDER BY %2"; - $p = [1 => [$name, 'String']]; + $p = [ + 1 => [$name, 'String'], + 2 => ['v.' . $orderBy, 'MysqlOrderBy'], + ]; $dao = CRM_Core_DAO::executeQuery($query, $p); $var = self::valuesCommon($dao, $flip, $grouping, $localize, $labelColumnName); diff --git a/tests/phpunit/CRM/Core/OptionGroupTest.php b/tests/phpunit/CRM/Core/OptionGroupTest.php index 5c3295b626..ca6f3bd5b2 100644 --- a/tests/phpunit/CRM/Core/OptionGroupTest.php +++ b/tests/phpunit/CRM/Core/OptionGroupTest.php @@ -136,4 +136,25 @@ class CRM_Core_OptionGroupTest extends CiviUnitTestCase { unset($original_domain, $domainIDs, $optionValues); } + public static function orderByCases(): array { + return [ + ['weight', FALSE], + ['id`; DELETE FROM contact; SELECT id FROM contact WHERE `id', TRUE], + ]; + } + + /** + * Test to ensure that OrderBy in CRM_Core_OptionGroup::values is sanitised + * @dataProvider orderByCases + */ + public function testOrderBy($case, $expectException): void { + try { + CRM_Core_OptionGroup::values('from_email_address', FALSE, FALSE, FALSE, NULL, 'label', TRUE, FALSE, 'value', $case); + $this->assertFalse($expectException); + } + catch (CRM_Core_Exception $e) { + $this->assertTrue($expectException); + } + } + } -- 2.25.1