VYPR
Medium severity4.3NVD Advisory· Published Apr 20, 2017· Updated May 13, 2026

CVE-2016-3733

CVE-2016-3733

Description

The "restore teacher" feature in Moodle 3.0 through 3.0.3, 2.9 through 2.9.5, 2.8 through 2.8.11, 2.7 through 2.7.13, and earlier allows remote authenticated users to overwrite the course idnumber.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
moodle/moodlePackagist
>= 2.7, < 2.7.142.7.14
moodle/moodlePackagist
>= 2.8, < 2.8.122.8.12
moodle/moodlePackagist
>= 2.9, < 2.9.62.9.6
moodle/moodlePackagist
>= 3.0, < 3.0.43.0.4

Affected products

44
  • Moodle/Moodle44 versions
    cpe:2.3:a:moodle:moodle:2.7.0:*:*:*:*:*:*:*+ 43 more
    • cpe:2.3:a:moodle:moodle:2.7.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.0:beta:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.0:rc1:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.0:rc2:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.3:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.4:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.5:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.6:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.11:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.12:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.13:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.7:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.8:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.9:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.10:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:3.0.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:3.0.0:beta:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.3:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.4:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.5:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.6:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.7:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.8:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.9:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.10:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.8.11:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.9.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.9.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.9.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.9.3:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.9.4:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.9.5:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:3.0.0:rc1:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:3.0.0:rc2:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:3.0.0:rc3:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:3.0.0:rc4:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:3.0.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:3.0.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:3.0.3:*:*:*:*:*:*:*

Patches

4
24b0c3c86ae9

MDL-51369 backup: Respect capabilities when restoring course info

https://github.com/moodle/moodleFrederic MassartApr 21, 2016via ghsa
1 file changed · +35 8
  • backup/moodle2/restore_stepslib.php+35 8 modified
    @@ -1478,27 +1478,54 @@ protected function define_structure() {
          */
         public function process_course($data) {
             global $CFG, $DB;
    +        $context = context::instance_by_id($this->task->get_contextid());
    +        $userid = $this->task->get_userid();
    +        $target = $this->get_task()->get_target();
    +        $isnewcourse = $target != backup::TARGET_CURRENT_ADDING && $target != backup::TARGET_EXISTING_ADDING;
    +
    +        // When restoring to a new course we can set all the things except for the ID number.
    +        $canchangeidnumber = $isnewcourse || has_capability('moodle/course:changeidnumber', $context, $userid);
    +        $canchangeshortname = $isnewcourse || has_capability('moodle/course:changeshortname', $context, $userid);
    +        $canchangefullname = $isnewcourse || has_capability('moodle/course:changefullname', $context, $userid);
    +        $canchangesummary = $isnewcourse || has_capability('moodle/course:changesummary', $context, $userid);
     
             $data = (object)$data;
    +        $data->id = $this->get_courseid();
     
             $fullname  = $this->get_setting_value('course_fullname');
             $shortname = $this->get_setting_value('course_shortname');
             $startdate = $this->get_setting_value('course_startdate');
     
    -        // Calculate final course names, to avoid dupes
    +        // Calculate final course names, to avoid dupes.
             list($fullname, $shortname) = restore_dbops::calculate_course_names($this->get_courseid(), $fullname, $shortname);
     
    -        // Need to change some fields before updating the course record
    -        $data->id = $this->get_courseid();
    -        $data->fullname = $fullname;
    -        $data->shortname= $shortname;
    +        if ($canchangefullname) {
    +            $data->fullname = $fullname;
    +        } else {
    +            unset($data->fullname);
    +        }
    +
    +        if ($canchangeshortname) {
    +            $data->shortname = $shortname;
    +        } else {
    +            unset($data->shortname);
    +        }
    +
    +        if (!$canchangesummary) {
    +            unset($data->summary);
    +            unset($data->summaryformat);
    +        }
     
             // Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
             // another course on this site.
    -        $context = context::instance_by_id($this->task->get_contextid());
    -        if (!empty($data->idnumber) && has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid()) &&
    -                $this->task->is_samesite() && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
    +        if (!empty($data->idnumber) && $canchangeidnumber && $this->task->is_samesite()
    +                && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
                 // Do not reset idnumber.
    +
    +        } else if (!$isnewcourse) {
    +            // Prevent override when restoring as merge.
    +            unset($data->idnumber);
    +
             } else {
                 $data->idnumber = '';
             }
    
3c9d2b104023

MDL-51369 backup: Respect capabilities when restoring course info

https://github.com/moodle/moodleFrederic MassartApr 21, 2016via ghsa
1 file changed · +35 8
  • backup/moodle2/restore_stepslib.php+35 8 modified
    @@ -1700,27 +1700,54 @@ protected function define_structure() {
          */
         public function process_course($data) {
             global $CFG, $DB;
    +        $context = context::instance_by_id($this->task->get_contextid());
    +        $userid = $this->task->get_userid();
    +        $target = $this->get_task()->get_target();
    +        $isnewcourse = $target != backup::TARGET_CURRENT_ADDING && $target != backup::TARGET_EXISTING_ADDING;
    +
    +        // When restoring to a new course we can set all the things except for the ID number.
    +        $canchangeidnumber = $isnewcourse || has_capability('moodle/course:changeidnumber', $context, $userid);
    +        $canchangeshortname = $isnewcourse || has_capability('moodle/course:changeshortname', $context, $userid);
    +        $canchangefullname = $isnewcourse || has_capability('moodle/course:changefullname', $context, $userid);
    +        $canchangesummary = $isnewcourse || has_capability('moodle/course:changesummary', $context, $userid);
     
             $data = (object)$data;
    +        $data->id = $this->get_courseid();
     
             $fullname  = $this->get_setting_value('course_fullname');
             $shortname = $this->get_setting_value('course_shortname');
             $startdate = $this->get_setting_value('course_startdate');
     
    -        // Calculate final course names, to avoid dupes
    +        // Calculate final course names, to avoid dupes.
             list($fullname, $shortname) = restore_dbops::calculate_course_names($this->get_courseid(), $fullname, $shortname);
     
    -        // Need to change some fields before updating the course record
    -        $data->id = $this->get_courseid();
    -        $data->fullname = $fullname;
    -        $data->shortname= $shortname;
    +        if ($canchangefullname) {
    +            $data->fullname = $fullname;
    +        } else {
    +            unset($data->fullname);
    +        }
    +
    +        if ($canchangeshortname) {
    +            $data->shortname = $shortname;
    +        } else {
    +            unset($data->shortname);
    +        }
    +
    +        if (!$canchangesummary) {
    +            unset($data->summary);
    +            unset($data->summaryformat);
    +        }
     
             // Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
             // another course on this site.
    -        $context = context::instance_by_id($this->task->get_contextid());
    -        if (!empty($data->idnumber) && has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid()) &&
    -                $this->task->is_samesite() && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
    +        if (!empty($data->idnumber) && $canchangeidnumber && $this->task->is_samesite()
    +                && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
                 // Do not reset idnumber.
    +
    +        } else if (!$isnewcourse) {
    +            // Prevent override when restoring as merge.
    +            unset($data->idnumber);
    +
             } else {
                 $data->idnumber = '';
             }
    
2950f9fb9128

MDL-51369 backup: Respect capabilities when restoring course info

https://github.com/moodle/moodleFrederic MassartApr 21, 2016via ghsa
1 file changed · +35 8
  • backup/moodle2/restore_stepslib.php+35 8 modified
    @@ -1700,27 +1700,54 @@ protected function define_structure() {
          */
         public function process_course($data) {
             global $CFG, $DB;
    +        $context = context::instance_by_id($this->task->get_contextid());
    +        $userid = $this->task->get_userid();
    +        $target = $this->get_task()->get_target();
    +        $isnewcourse = $target != backup::TARGET_CURRENT_ADDING && $target != backup::TARGET_EXISTING_ADDING;
    +
    +        // When restoring to a new course we can set all the things except for the ID number.
    +        $canchangeidnumber = $isnewcourse || has_capability('moodle/course:changeidnumber', $context, $userid);
    +        $canchangeshortname = $isnewcourse || has_capability('moodle/course:changeshortname', $context, $userid);
    +        $canchangefullname = $isnewcourse || has_capability('moodle/course:changefullname', $context, $userid);
    +        $canchangesummary = $isnewcourse || has_capability('moodle/course:changesummary', $context, $userid);
     
             $data = (object)$data;
    +        $data->id = $this->get_courseid();
     
             $fullname  = $this->get_setting_value('course_fullname');
             $shortname = $this->get_setting_value('course_shortname');
             $startdate = $this->get_setting_value('course_startdate');
     
    -        // Calculate final course names, to avoid dupes
    +        // Calculate final course names, to avoid dupes.
             list($fullname, $shortname) = restore_dbops::calculate_course_names($this->get_courseid(), $fullname, $shortname);
     
    -        // Need to change some fields before updating the course record
    -        $data->id = $this->get_courseid();
    -        $data->fullname = $fullname;
    -        $data->shortname= $shortname;
    +        if ($canchangefullname) {
    +            $data->fullname = $fullname;
    +        } else {
    +            unset($data->fullname);
    +        }
    +
    +        if ($canchangeshortname) {
    +            $data->shortname = $shortname;
    +        } else {
    +            unset($data->shortname);
    +        }
    +
    +        if (!$canchangesummary) {
    +            unset($data->summary);
    +            unset($data->summaryformat);
    +        }
     
             // Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
             // another course on this site.
    -        $context = context::instance_by_id($this->task->get_contextid());
    -        if (!empty($data->idnumber) && has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid()) &&
    -                $this->task->is_samesite() && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
    +        if (!empty($data->idnumber) && $canchangeidnumber && $this->task->is_samesite()
    +                && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
                 // Do not reset idnumber.
    +
    +        } else if (!$isnewcourse) {
    +            // Prevent override when restoring as merge.
    +            unset($data->idnumber);
    +
             } else {
                 $data->idnumber = '';
             }
    
12c28574868d

MDL-51369 backup: Respect capabilities when restoring course info

https://github.com/moodle/moodleFrederic MassartApr 21, 2016via ghsa
1 file changed · +35 8
  • backup/moodle2/restore_stepslib.php+35 8 modified
    @@ -1686,27 +1686,54 @@ protected function define_structure() {
          */
         public function process_course($data) {
             global $CFG, $DB;
    +        $context = context::instance_by_id($this->task->get_contextid());
    +        $userid = $this->task->get_userid();
    +        $target = $this->get_task()->get_target();
    +        $isnewcourse = $target != backup::TARGET_CURRENT_ADDING && $target != backup::TARGET_EXISTING_ADDING;
    +
    +        // When restoring to a new course we can set all the things except for the ID number.
    +        $canchangeidnumber = $isnewcourse || has_capability('moodle/course:changeidnumber', $context, $userid);
    +        $canchangeshortname = $isnewcourse || has_capability('moodle/course:changeshortname', $context, $userid);
    +        $canchangefullname = $isnewcourse || has_capability('moodle/course:changefullname', $context, $userid);
    +        $canchangesummary = $isnewcourse || has_capability('moodle/course:changesummary', $context, $userid);
     
             $data = (object)$data;
    +        $data->id = $this->get_courseid();
     
             $fullname  = $this->get_setting_value('course_fullname');
             $shortname = $this->get_setting_value('course_shortname');
             $startdate = $this->get_setting_value('course_startdate');
     
    -        // Calculate final course names, to avoid dupes
    +        // Calculate final course names, to avoid dupes.
             list($fullname, $shortname) = restore_dbops::calculate_course_names($this->get_courseid(), $fullname, $shortname);
     
    -        // Need to change some fields before updating the course record
    -        $data->id = $this->get_courseid();
    -        $data->fullname = $fullname;
    -        $data->shortname= $shortname;
    +        if ($canchangefullname) {
    +            $data->fullname = $fullname;
    +        } else {
    +            unset($data->fullname);
    +        }
    +
    +        if ($canchangeshortname) {
    +            $data->shortname = $shortname;
    +        } else {
    +            unset($data->shortname);
    +        }
    +
    +        if (!$canchangesummary) {
    +            unset($data->summary);
    +            unset($data->summaryformat);
    +        }
     
             // Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
             // another course on this site.
    -        $context = context::instance_by_id($this->task->get_contextid());
    -        if (!empty($data->idnumber) && has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid()) &&
    -                $this->task->is_samesite() && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
    +        if (!empty($data->idnumber) && $canchangeidnumber && $this->task->is_samesite()
    +                && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
                 // Do not reset idnumber.
    +
    +        } else if (!$isnewcourse) {
    +            // Prevent override when restoring as merge.
    +            unset($data->idnumber);
    +
             } else {
                 $data->idnumber = '';
             }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.