Moderate severityNVD Advisory· Published Nov 24, 2014· Updated May 6, 2026
CVE-2014-7831
CVE-2014-7831
Description
lib/classes/grades_external.php in Moodle 2.7.x before 2.7.3 does not consider the moodle/grade:viewhidden capability before displaying hidden grades, which allows remote authenticated users to obtain sensitive information by leveraging the student role to access the get_grades web service.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
moodle/moodlePackagist | >= 2.7.0, < 2.7.3 | 2.7.3 |
Affected products
19cpe:2.3:a:moodle:moodle:*:*:*:*:*:*:*:*+ 18 more
- cpe:2.3:a:moodle:moodle:*:*:*:*:*:*:*:*range: <=2.4.11
- cpe:2.3:a:moodle:moodle:2.5.0:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.5.1:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.5.2:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.5.3:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.5.4:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.5.5:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.5.6:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.5.7:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.5.8:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.6.0:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.6.1:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.6.2:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.6.3:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.6.4:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.6.5:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.7.0:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.7.1:*:*:*:*:*:*:*
- cpe:2.3:a:moodle:moodle:2.7.2:*:*:*:*:*:*:*
Patches
13b8876f5ef2bMDL-47766 web services: get_grades exposes hidden grades to students
3 files changed · +37 −27
lib/classes/grades_external.php+5 −1 modified@@ -55,7 +55,9 @@ public static function get_grades_parameters() { } /** - * Retrieve grade items and, optionally, student grades + * Returns student course total grade and grades for activities. + * This function does not return category or manual items. + * This function is suitable for managers or teachers not students. * * @param int $courseid Course id * @param string $component Component name @@ -86,6 +88,8 @@ public static function get_grades($courseid, $component = null, $activityid = nu throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); } + require_capability('moodle/grade:viewhidden', $coursecontext); + $course = $DB->get_record('course', array('id' => $params['courseid']), '*', MUST_EXIST); $access = false;
lib/db/services.php+4 −3 modified@@ -104,9 +104,11 @@ 'core_grades_get_grades' => array( 'classname' => 'core_grades_external', 'methodname' => 'get_grades', - 'description' => 'Returns grade item details and optionally student grades.', + 'description' => 'Returns student course total grade and grades for activities. + This function does not return category or manual items. + This function is suitable for managers or teachers not students.', 'type' => 'read', - 'capabilities' => 'moodle/grade:view, moodle/grade:viewall', + 'capabilities' => 'moodle/grade:view, moodle/grade:viewall, moodle/grade:viewhidden', ), 'core_grades_update_grades' => array( @@ -946,7 +948,6 @@ 'mod_assign_reveal_identities', 'message_airnotifier_is_system_configured', 'message_airnotifier_are_notification_preferences_configured', - 'core_grades_get_grades', 'core_grades_update_grades', 'mod_forum_get_forums_by_courses', 'mod_forum_get_forum_discussions',
lib/tests/grades_externallib_test.php+28 −23 modified@@ -150,8 +150,8 @@ public function test_get_grades() { $this->load_test_data($assignmentname, $student1rawgrade, $student2rawgrade); $assigmentcm = get_coursemodule_from_id('assign', $assignment->id, 0, false, MUST_EXIST); - // Student requesting their own grade for the assignment. - $this->setUser($student1); + // Teacher requesting a student grade for the assignment. + $this->setUser($teacher); $grades = core_grades_external::get_grades( $course->id, 'mod_assign', @@ -161,7 +161,7 @@ public function test_get_grades() { $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades); $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigmentcm->id, $student1->id)); - // Student requesting all of their grades in a course. + // Teacher requesting all the grades of student1 in a course. $grades = core_grades_external::get_grades( $course->id, null, @@ -177,7 +177,20 @@ public function test_get_grades() { $this->assertEquals($outcome['name'], 'Team work'); $this->assertEquals(0, $this->get_outcome_student_grade($grades, $assigmentcm->id, $student1->id)); + // Teacher requesting all the grades of all the students in a course. + $grades = core_grades_external::get_grades( + $course->id, + null, + null, + array($student1->id, $student2->id) + ); + $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades); + $this->assertTrue(count($grades['items']) == 2); + $this->assertTrue(count($grades['items'][0]['grades']) == 2); + $this->assertTrue(count($grades['items'][1]['grades']) == 2); + // Student requesting another student's grade for the assignment (should fail). + $this->setUser($student1); try { $grades = core_grades_external::get_grades( $course->id, @@ -190,16 +203,19 @@ public function test_get_grades() { $this->assertTrue(true); } - // Parent requesting their child's grade for the assignment. + // Parent requesting their child's grade for the assignment (should fail). $this->setUser($parent); - $grades = core_grades_external::get_grades( - $course->id, - 'mod_assign', - $assigmentcm->id, - array($student1->id) - ); - $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades); - $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigmentcm->id, $student1->id)); + try { + $grades = core_grades_external::get_grades( + $course->id, + 'mod_assign', + $assigmentcm->id, + array($student1->id) + ); + $this->fail('moodle_exception expected'); + } catch (moodle_exception $ex) { + $this->assertTrue(true); + } // Parent requesting another student's grade for the assignment(should fail). try { @@ -294,17 +310,6 @@ public function test_get_grades() { $grades = grade_get_grades($course->id, 'mod', 'assign', $assignment->id); $this->assertEquals($grades->items[0]->hidden, 1); - // Student should now not be able to see it. - $this->setUser($student1); - $grades = core_grades_external::get_grades( - $course->id, - 'mod_assign', - $assigmentcm->id, - array($student1->id) - ); - $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades); - $this->assertEquals(null, $this->get_activity($grades, $assigmentcm->id)); - // Teacher should still be able to see the hidden grades. $this->setUser($teacher); $grades = core_grades_external::get_grades(
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-59j6-8g7w-prf7ghsaADVISORY
- moodle.org/mod/forum/discuss.phpnvdVendor AdvisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2014-7831ghsaADVISORY
- openwall.com/lists/oss-security/2014/11/17/11nvdWEB
- github.com/moodle/moodle/commit/3b8876f5ef2b5cde1e9de2599efd03d02bdaf7d8ghsaWEB
- web.archive.org/web/20150914064838/http://www.securitytracker.com/id/1031215ghsaWEB
- www.securitytracker.com/id/1031215nvd
News mentions
0No linked articles in our index yet.