CVE-2026-58333
Patch Available.
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Moodle is an open source learning management system written in PHP. Schools, universities, and companies use it to run online courses. IOMAD is a multi-tenant distribution of Moodle that lets one installation serve several companies or organizations; it is built on Moodle core and shares the affected code. Moodle can export a course, including its uploaded files, as a backup file that can be restored into the same site or a different one. Inside the backup, files.xml describes each file and the file contents are stored in a files/ directory, named by their SHA-1 content hash.
A Path Traversal vulnerability (CVE-2026-58333) has been identified in the backup restore process of Moodle and IOMAD, which allows a user who can restore a backup to read arbitrary files from the server by supplying a crafted content hash in the backup's file records. Moodle tracks this issue as MSA-26-0014 (MDL-88736).
Per OWASP: A path traversal attack (also known as directory traversal) aims to access files and directories that are stored outside the web root folder. By manipulating variables that reference files with “dot-dot-slash (../)” sequences and its variations or by using absolute file paths, it may be possible to access arbitrary files and directories stored on file system including application source code or configuration and critical system files.
This issue affects all versions of Moodle before 4.5.12, versions 5.0.0 through 5.0.7, versions 5.1.0 through 5.1.4, and version 5.2.0, including End-of-Life release lines such as Moodle 4.3. IOMAD releases built on these Moodle versions contain the same code and are affected as well.
Details
Module Info
- Product: Moodle, IOMAD
- Affected packages:
moodle/moodle(backup/moodle2/restore_stepslib.php) - Affected versions: <4.5.12, >=5.0.0 <5.0.8, >=5.1.0 <5.1.5, >=5.2.0 <5.2.1
- GitHub repository: https://github.com/moodle/moodle (Moodle), https://github.com/iomad/iomad (IOMAD)
- Published packages: https://packagist.org/packages/moodle/moodle
- Package manager: Composer
- Fixed in:
- OSS Moodle 4.5.12, 5.0.8, 5.1.5, 5.2.1
- NES for Moodle v4.3.13
- NES for IOMAD v4.3.4
Vulnerability Info
This High-severity vulnerability is found in the moodle/moodle package in all versions before 4.5.12, 5.0.0 through 5.0.7, 5.1.0 through 5.1.4, and 5.2.0 of Moodle, and in IOMAD releases built on those versions. Moodle rates it Serious.
During restore, restore_load_included_files::process_file() reads each <file> element from files.xml and stores it for later steps without checking its fields. When the files are copied into the target site, restore_dbops::send_files_to_pool() turns the contenthash value from that record into a path inside the extracted backup and copies whatever is there into Moodle's file storage:
// this is a regular file, it must be present in the backup pool
$backuppath = $basepath . backup_file_manager::get_backup_content_file_location($file->contenthash);get_backup_content_file_location() only joins the first two characters of the hash and the hash itself:
public static function get_backup_content_file_location($contenthash) {
$l1 = $contenthash[0].$contenthash[1];
return "$l1/$contenthash";
}A real content hash is 40 hexadecimal characters, but nothing enforced that. A crafted backup can set contenthash to a value made of ../ segments followed by the path of a file on the server, such as Moodle's config.php. The restore then copies that file into a file area of the restored course, where the user can download it. For backups that do not include file contents, the same hash is used to look the file up in Moodle's own file storage, which builds its path from the hash in a similar way.
Exploitation requires an account that can restore content. The moodle/restore:restorecourse and moodle/restore:restoreactivity capabilities are granted by default to the Manager and Teacher roles in their courses, so on a typical site a teacher can reach this code. Any file the web server user can read is exposed, including config.php with the database password, which can lead to a full compromise of the site. Users without restore capabilities are not exposed.
The fix rejects any file record whose contenthash is not exactly 40 lowercase hexadecimal characters as soon as it is read, logs a warning, and skips the file:
// Reject invalid contenthash values early to prevent path traversal.
if (!empty($data->contenthash) && !preg_match('/^[a-f0-9]{40}$/', $data->contenthash)) {
$filename = isset($data->filename) ? $data->filename : '';
$this->log(
'Skipping file with invalid contenthash during restore: ' . $filename,
backup::LOG_WARNING
);
return;
}Mitigation
Moodle publishes security fixes only for its supported release lines. Earlier release lines, including Moodle 4.3 and the IOMAD releases built on it, are End-of-Life and will not receive any public updates to address this issue.
Until an upgrade is possible, restrict the moodle/restore:restorecourse, moodle/restore:restoresection, and moodle/restore:restoreactivity capabilities to trusted roles, and do not restore backup files from untrusted sources.
Users of the affected components should apply one of the following mitigations:
- Upgrade to Moodle 4.5.12, 5.0.8, 5.1.5, 5.2.1, or later, or to an IOMAD release built on one of those versions.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.
Credits
- LoWeST (finder)