CVE-2026-58332
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's multi-factor authentication (MFA) tool, tool_mfa, has been part of core since Moodle 4.3. Its email factor sends the user a six-digit code, and a link that contains the code, after they enter their password.
An Authentication Bypass vulnerability (CVE-2026-58332) has been identified in the email factor of the multi-factor authentication tool in Moodle and IOMAD, which allows an attacker who already knows a user's password to pass that user's email check with a code sent to a different account. Only sites that enable MFA with the email factor are affected. Moodle tracks this issue as MSA-26-0013 (MDL-88767).
Per MITRE CWE-287: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
This issue affects Moodle versions 4.3.0 through 4.5.11, 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(admin/tool/mfa/factor/email) - Affected versions: >=4.3.0 <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 versions 4.3.0 through 4.5.11, 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's advisory also lists earlier unsupported versions; the MFA tool first shipped in core with Moodle 4.3. Moodle rates it Serious.
When the email factor runs, Moodle stores a record in the tool_mfa table with the code as its secret, and emails the user a link to admin/tool/mfa/factor/email/email.php that carries the record ID in instance, the code in secret, and pass=1. The email factor registers this page as one that MFA does not redirect away from, so a user who has entered a password but not yet finished MFA can open it. With pass set, the page only checked that the secret matched the record named in the URL:
// If pass is set, do checks and pass for this session.
// Require login to force $SESSION and user, and pass for that session.
if (!empty($instance) && $pass != 0 && $secret != 0) {
require_login();
if ($factor->get_state() === \tool_mfa\plugininfo\factor::STATE_LOCKED) {
// Redirect through to auth, this will bounce them to the next factor.
redirect(new moodle_url('/admin/tool/mfa/auth.php'));
}
// Check the code with the same measures on the page entry.
if ($instance->secret != $secret) {
\tool_mfa\manager::sleep_timer();
$factor->increment_lock_counter();
throw new moodle_exception('error:parameters', 'factor_email');
}Nothing tied the tool_mfa record to the user who was logged in. Any record ID and code that matched each other were accepted, and the page then set the email factor to STATE_PASS for the current session. An attacker who has an account of their own on the site can start a login on that account to receive a valid record ID and code by email, then log in as the victim with the victim's password and open the link with their own values. The victim's email factor is marked as passed without any code being sent to the victim.
The attacker still needs the victim's username and password, as Moodle's advisory notes. The flaw removes the protection that the email factor is meant to add once a password has been stolen or guessed, and where the email factor carries enough weight to complete MFA on its own, the attacker ends up fully logged in as the victim. Sites that do not enable the email factor are not exposed.
The fix checks that the record belongs to the logged-in user before doing anything else with it:
if (!empty($instance) && $pass != 0 && $secret != 0) {
require_login();
if ((int)$instance->userid !== (int)$USER->id) {
throw new moodle_exception('error:parameters', 'factor_email');
}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, sites can disable the email factor in the multi-factor authentication settings and rely on other factors, such as an authenticator app (TOTP).
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
- Brendan Heywood (finder)