Security advisory GHSA-7h8v-2v8x-h264: SQL Injection in moodle
Package: moodle/moodle (composer), vulnerable version: v3.9.2, fixed in: 3.9.3
CWE: CWE-89
Files changed by the fix:
mod/data/classes/external.php

Fix diff:
diff --git a/mod/data/classes/external.php b/mod/data/classes/external.php
index 4811a6c544542..0b4f1c203dd05 100644
--- a/mod/data/classes/external.php
+++ b/mod/data/classes/external.php
@@ -266,6 +266,7 @@ public static function get_data_access_information($databaseid, $groupid = 0) {
             'warnings' => $warnings
         );
 
+        $groupmode = groups_get_activity_groupmode($cm);
         if (!empty($params['groupid'])) {
             $groupid = $params['groupid'];
             // Determine is the group is visible to user.
@@ -274,7 +275,6 @@ public static function get_data_access_information($databaseid, $groupid = 0) {
             }
         } else {
             // Check to see if groups are being used here.
-            $groupmode = groups_get_activity_groupmode($cm);
             if ($groupmode) {
                 $groupid = groups_get_activity_group($cm);
             } else {
@@ -981,10 +981,10 @@ public static function add_entry($databaseid, $groupid, $data) {
         // Check database is open in time.
         data_require_time_available($database, null, $context);
 
+        $groupmode = groups_get_activity_groupmode($cm);
         // Determine default group.
         if (empty($params['groupid'])) {
             // Check to see if groups are being used here.
-            $groupmode = groups_get_activity_groupmode($cm);
             if ($groupmode) {
                 $groupid = groups_get_activity_group($cm);
             } else {
diff --git a/mod/data/tests/externallib_test.php b/mod/data/tests/externallib_test.php
index 815744c5b60ff..b796df0fbbb7b 100644
--- a/mod/data/tests/externallib_test.php
+++ b/mod/data/tests/externallib_test.php
@@ -379,6 +379,45 @@ public function test_get_data_access_information_teacher() {
         $this->assertEquals(0, $result['entrieslefttoview']);
     }
 
+    /**
+     * Test get_data_access_information with groups.
+     */
+    public function test_get_data_access_information_groups() {
+        global $DB;
+
+        $DB->set_field('course', 'groupmode', VISIBLEGROUPS, ['id' => $this->course->id]);
+
+        // Check I can see my group.
+        $this->setUser($this->student1);
+
+        $result = mod_data_external::get_data_access_information($this->database->id);
+        $result = external_api::clean_returnvalue(mod_data_external::get_data_access_information_returns(), $result);
+
+        $this->assertEquals($this->group1->id, $result['groupid']); // My group is correctly found.
+        $this->assertFalse($result['canmanageentries']);
+        $this->assertFalse($result['canapprove']);
+        $this->assertTrue($result['canaddentry']);  // I can entries in my groups.
+        $this->assertTrue($result['timeavailable']);
+        $this->assertFalse($result['inreadonlyperiod']);
+        $this->assertEquals(0, $result['numentries']);
+        $this->assertEquals(0, $result['entrieslefttoadd']);
+        $this->assertEquals(0, $result['entrieslefttoview']);
+
+        // Check the other course group in visible groups mode.
+        $result = mod_data_external::get_data_access_information($this->database->id, $this->group2->id);
+        $result = external_api::clean_returnvalue(mod_data_external::get_data_access_information_returns(), $result);
+
+        $this->assertEquals($this->group2->id, $result['groupid']); // The group is correctly found.
+        $this->assertFalse($result['canmanageentries']);
+        $this->assertFalse($result['canapprove']);
+        $this->assertFalse($result['canaddentry']);  // I cannot add entries in other groups.
+        $this->assertTrue($result['timeavailable']);
+        $this->assertFalse($result['inreadonlyperiod']);
+        $this->assertEquals(0, $result['numentries']);
+        $this->assertEquals(0, $result['entrieslefttoadd']);
+        $this->assertEquals(0, $result['entrieslefttoview']);
+    }
+
     /**
      * Helper method to populate the database with some entries.
      *
@@ -1095,6 +1134,16 @@ public function test_add_entry_max_num_entries() {
         mod_data_external::add_entry($this->database->id, 0, []);
     }
 
+    /**
+     * Test add_entry invalid group.
+     */
+    public function test_add_entry_invalid_group() {
+        $this->setUser($this->student1);
+        $this->expectExceptionMessage(get_string('noaccess', 'data'));
+        $this->expectException('moodle_exception');
+        mod_data_external::add_entry($this->database->id, $this->group2->id, []);
+    }
+
     /**
      * Test update_entry.
      */