From: CiviCRM Date: Sat, 2 Sep 2023 05:13:38 +0000 (-0700) Subject: CIVI-SA-2023-09 - SQLI via API getFields X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=7603eb1af469119db267b858c89514d041ec73ba;p=civicrm-core.git CIVI-SA-2023-09 - SQLI via API getFields --- 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); + } + } + }