CIVI-SA-2023-09 - SQLI via API getFields
authorCiviCRM <info@civicrm.org>
Sat, 2 Sep 2023 05:13:38 +0000 (22:13 -0700)
committerSeamus Lee <seamuslee001@gmail.com>
Thu, 7 Sep 2023 00:19:10 +0000 (10:19 +1000)
CRM/Contact/BAO/Contact.php
CRM/Core/OptionGroup.php
tests/phpunit/CRM/Core/OptionGroupTest.php

index a925762dd4690f1572db28c0a350732d0dd9b51d..2c21311b9d6daeb662a119a4ca3490e78a16029a 100644 (file)
@@ -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;
 
index dac6a726aed7a56262c54768e95fcf062aa9732c..f6a2a0d866c2488a5054e406aebdffa535109be1 100644 (file)
@@ -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);
index 5c3295b62642af41af4732534b95550b514c6f9c..ca6f3bd5b2a178273ee23c9c5bbe4e71bca8bc43 100644 (file)
@@ -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);
+    }
+  }
+
 }