VYPR
Medium severity4.3NVD Advisory· Published Jul 17, 2017· Updated May 13, 2026

CVE-2017-7531

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.

PackageAffected versionsPatched versions
moodle/moodlePackagist
< 3.3.13.3.1

Affected products

2

Patches

1
2fe7f706d756

MDL-59304 core_calendar: check if course is hidden in bailout callback

https://github.com/moodle/moodleMark NelsonJun 22, 2017via ghsa
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

News mentions

0

No linked articles in our index yet.