CVE-2025-49513
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. Each page tells Moodle whether the browser may cache it, and Moodle sends HTTP caching headers to match.
An Information Exposure vulnerability (CVE-2025-49513) has been identified in the login page of Moodle and IOMAD, which allows a person with access to the same web browser to recover a user's password from the cached login page after that user has logged out. Moodle tracks this issue as MSA-25-0030 (MDL-85323).
Per MITRE CWE-525: The web application does not use an appropriate caching policy that specifies the extent to which each web page and associated form fields should be cached.
This issue affects all versions of Moodle before 4.1.19, versions 4.2.0 through 4.4.8, versions 4.5.0 through 4.5.4, and version 5.0.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(login/index.php,lib/weblib.php) - Affected versions: <4.1.19, >=4.2.0 <4.4.9, >=4.5.0 <4.5.5, >=5.0.0 <5.0.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.1.19, 4.4.9, 4.5.5, 5.0.1
- NES for Moodle v4.3.13
- NES for IOMAD v4.3.4
Vulnerability Info
This Low-severity vulnerability is found in the moodle/moodle package in all versions before 4.1.19, 4.2.0 through 4.4.8, 4.5.0 through 4.5.4, and 5.0.0 of Moodle, and in IOMAD releases built on those versions. Moodle rates it Minor.
Moodle pages are cacheable unless they say otherwise (moodle_page::$_cacheable defaults to true), and login/index.php did not change that. For a cacheable page, send_headers() in lib/weblib.php sends headers that let the browser keep the page for its Back button:
if ($cacheable) {
// Allow caching on "back" (but not on normal clicks).
@header('Cache-Control: private, pre-check=0, post-check=0, max-age=0, no-transform');
@header('Pragma: no-cache');
@header('Expires: ');
} else {
// Do everything we can to always prevent clients and proxies caching.
@header('Cache-Control: no-store, no-cache, must-revalidate');
@header('Cache-Control: post-check=0, pre-check=0, no-transform', false);
@header('Pragma: no-cache');
@header('Expires: Mon, 20 Aug 1969 09:23:00 GMT');
@header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
}Browsers can restore a page kept this way together with the values that were typed into its form fields. After a user logs in, uses the site, and logs out, someone at the same browser can go back through the history to the login page and may find the user's password still in the password field, where it can be read by inspecting the page.
As Moodle's advisory notes, this requires access to the web browser on the device where the user logged in. Shared computers, such as those in libraries, labs, and classrooms, carry the most risk. The cached page is not reachable from other devices.
The fix marks the login page as not cacheable:
$context = context_system::instance();
$PAGE->set_url("$CFG->wwwroot/login/index.php");
$PAGE->set_context($context);
$PAGE->set_pagelayout('login');
$PAGE->set_cacheable(false);With that set, send_headers() takes its no-cache branch. The fix also merges the two Cache-Control headers in that branch into a single no-store, no-cache, must-revalidate, no-transform header, which tells the browser not to store the page.
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.
Users of the affected components should apply one of the following mitigations:
- Upgrade to Moodle 4.1.19, 4.4.9, 4.5.5, 5.0.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
- Mark Johnson (finder)