security/core#73 - Fix Contact.getquick API key exposure
authorPatrick Figel <pfigel@greenpeace.org>
Tue, 18 Feb 2020 20:54:05 +0000 (21:54 +0100)
committerSeamus Lee <seamuslee001@gmail.com>
Thu, 16 Apr 2020 01:03:21 +0000 (11:03 +1000)
This fixes an issue where API keys can be exposed via the field_name
parameter of the Contact.getquick API. Since there is no valid use-case
for requesting API keys via getquick, the fix simply triggers an API
error if the API key is requested.

api/v3/Contact.php
tests/phpunit/api/v3/ContactTest.php

index ba581e57947526c3d6199e49436b29608c247613..bbbf007576b99df5165b90869be1821cb5abf8e8 100644 (file)
@@ -765,6 +765,10 @@ function civicrm_api3_contact_getquick($params) {
   // If we are doing quicksearch by a field other than name, make sure that field is added to results
   if (!empty($params['field_name'])) {
     $field_name = CRM_Utils_String::munge($params['field_name']);
+    // there is no good reason to request api_key via getquick
+    if ($field_name == 'api_key') {
+      throw new API_Exception('Illegal value "api_key" for parameter "field_name"');
+    }
     // Unique name contact_id = id
     if ($field_name == 'contact_id') {
       $field_name = 'id';
index 90f0e22e82f601b5b016cb6ebb5db9f3bc41128a..55bf5055352fb3932bae84876b16107298a389ad 100644 (file)
@@ -3479,6 +3479,23 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
   }
 
+  /**
+   * Test that getquick doesn't work with field_name=api_key
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testGetQuickApiKey() {
+    $this->callAPISuccess('Contact', 'create', [
+      'contact_type' => 'Individual',
+      'email' => 'apiuser@example.com',
+      'api_key' => 'hunter2',
+    ]);
+    $result = $this->callAPIFailure('Contact', 'getquick', [
+      'name' => '%',
+      'field_name' => 'api_key',
+    ], 'Illegal value "api_key" for parameter "field_name"');
+  }
+
   /**
    * Set up some sample data for testing quicksearch.
    */