CVE-2017-7531
Description
In Moodle 3.3, the course overview block discloses activities from hidden courses to users lacking proper visibility checks.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
In Moodle 3.3, the course overview block discloses activities from hidden courses to users lacking proper visibility checks.
Vulnerability
In Moodle 3.3, the course overview block (used to display upcoming events and activities) fails to properly check course visibility before revealing activities. The bug resides in the get_event_factory callback, where the code checks module visibility but does not verify whether the parent course is hidden. The vulnerability affects Moodle 3.3 only; versions 3.3.1 and later include the fix [1][2][4].
Exploitation
An attacker needs no special network position beyond normal authenticated access to the Moodle site. No additional privileges beyond a standard user account are required. The exploit occurs when a user views the course overview block; the block renders activities that belong to courses that are hidden (i.e., not visible to that user). The code path is reachable for any user who has a role that allows viewing the course overview block, and who is enrolled in or has view capability on a hidden course [1][4].
Impact
An attacker who successfully exploits this vulnerability can see the existence and details of activities (such as assignments, forums, quizzes) within hidden courses. This information disclosure could reveal course materials, upcoming deadlines, or other sensitive content that the course instructor intended to keep hidden from certain users [1][2].
Mitigation
The vulnerability is fixed in Moodle 3.3.1, released on 2017-07-17. Administrators should upgrade to Moodle 3.3.1 or later [1][4]. No workaround is documented; upgrading is the recommended mitigation. The vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
moodle/moodlePackagist | < 3.3.1 | 3.3.1 |
Affected products
2Patches
12fe7f706d756MDL-59304 core_calendar: check if course is hidden in bailout callback
2 files changed · +66 −4
calendar/classes/local/event/container.php+9 −4 modified@@ -137,10 +137,15 @@ function ($dbrow) { // have that capability set on the "Authenticated User" role rather than // on "Student" role, which means uservisible returns true even when the user // is no longer enrolled in the course. - $modulecontext = \context_module::instance($cm->id); - // A user with the 'moodle/course:view' capability is able to see courses - // that they are not a participant in. - $canseecourse = (has_capability('moodle/course:view', $modulecontext) || is_enrolled($modulecontext)); + // So, with the following we are checking - + // 1) Only process modules if $cm->uservisible is true. + // 2) Only process modules for courses a user has the capability to view OR they are enrolled in. + // 3) Only process modules for courses that are visible OR if the course is not visible, the user + // has the capability to view hidden courses. + $coursecontext = \context_course::instance($dbrow->courseid); + $canseecourse = has_capability('moodle/course:view', $coursecontext) || is_enrolled($coursecontext); + $canseecourse = $canseecourse && + ($cm->get_course()->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)); if (!$cm->uservisible || !$canseecourse) { return true; }
calendar/tests/container_test.php+57 −0 modified@@ -183,6 +183,63 @@ public function test_event_factory_when_module_visibility_is_toggled_as_guest($d $this->assertNull($event); } + /** + * Test that the event factory deals with invisible courses as an admin. + * + * @dataProvider get_event_factory_testcases() + * @param \stdClass $dbrow Row from the "database". + */ + public function test_event_factory_when_course_visibility_is_toggled_as_admin($dbrow) { + $legacyevent = $this->create_event($dbrow); + $factory = \core_calendar\local\event\container::get_event_factory(); + + // Create a hidden course with an assignment. + $course = $this->getDataGenerator()->create_course(['visible' => 0]); + $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); + $moduleinstance = $generator->create_instance(['course' => $course->id]); + + $dbrow->id = $legacyevent->id; + $dbrow->courseid = $course->id; + $dbrow->instance = $moduleinstance->id; + $dbrow->modulename = 'assign'; + $event = $factory->create_instance($dbrow); + + // Module is still visible to admins even if the course is invisible. + $this->assertInstanceOf(event_interface::class, $event); + } + + /** + * Test that the event factory deals with invisible courses as a student. + * + * @dataProvider get_event_factory_testcases() + * @param \stdClass $dbrow Row from the "database". + */ + public function test_event_factory_when_course_visibility_is_toggled_as_student($dbrow) { + $legacyevent = $this->create_event($dbrow); + $factory = \core_calendar\local\event\container::get_event_factory(); + + // Create a hidden course with an assignment. + $course = $this->getDataGenerator()->create_course(['visible' => 0]); + $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); + $moduleinstance = $generator->create_instance(['course' => $course->id]); + + // Enrol a student into this course. + $student = $this->getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($student->id, $course->id); + + // Set the user to the student. + $this->setUser($student); + + $dbrow->id = $legacyevent->id; + $dbrow->courseid = $course->id; + $dbrow->instance = $moduleinstance->id; + $dbrow->modulename = 'assign'; + $event = $factory->create_instance($dbrow); + + // Module is invisible to students if the course is invisible. + $this->assertNull($event); + } + /** * Test that the event factory deals with completion related events properly. */
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- moodle.org/mod/forum/discuss.phpnvdPatchVendor AdvisoryWEB
- www.securityfocus.com/bid/99618nvdThird Party AdvisoryVDB Entry
- github.com/advisories/GHSA-w2pj-r8m3-r4jcghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-7531ghsaADVISORY
- github.com/moodle/moodle/commit/2fe7f706d7567babd6c7aeb6612f231d2ce2fb2fghsaWEB
- web.archive.org/web/20210124081202/http://www.securityfocus.com/bid/99618ghsaWEB
News mentions
0No linked articles in our index yet.