CVE-2025-67850
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. The Atto and TinyMCE text editors each include an equation editor plugin (atto_equation and tiny_equation) that lets users write TeX formulas and shows a live preview of the rendered result.
A Cross-Site Scripting (XSS) vulnerability (CVE-2025-67850) has been identified in the formula (equation) editor of Moodle and IOMAD, which allows HTML in the text of an equation to be inserted into the editor's preview without sanitizing and run as script in the browser of the user who opens it. Moodle tracks this issue as MSA-25-0054 (MDL-85557).
Per OWASP: Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user.
This issue affects all versions of Moodle before 4.1.22, versions 4.2.0 through 4.4.11, versions 4.5.0 through 4.5.7, versions 5.0.0 through 5.0.3, and version 5.1.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(lib/editor/atto/plugins/equation,lib/editor/tiny/plugins/equation) - Affected versions: <4.1.22, >=4.2.0 <4.4.12, >=4.5.0 <4.5.8, >=5.0.0 <5.0.4, >=5.1.0 <5.1.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.22, 4.4.12, 4.5.8, 5.0.4, 5.1.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.1.22, 4.2.0 through 4.4.11, 4.5.0 through 4.5.7, 5.0.0 through 5.0.3, and 5.1.0 of Moodle, and in IOMAD releases built on those versions. Moodle rates it Serious.
To build the preview, the equation editor sends the equation text, wrapped in TeX delimiters, to the server, runs it through the site's text filters, and writes the returned HTML into the dialog. When the cursor is on an existing equation in the editor content, the dialog loads that equation's source into its text area and previews it. In TinyMCE the text goes through the tiny_equation_filter web service, which accepted raw content and returned the filtered result:
public static function execute(int $contextid, string $content): array {
...
$context = context::instance_by_id($contextid);
self::validate_context($context);
$result = filter_manager::instance()->filter_text($content, $context);
return [
'content' => $result,
];
}The client then assigned that result to innerHTML:
equation = Selectors.delimiters.start + ' ' + equation + ' ' + Selectors.delimiters.end;
TinyEquationRepository.filterEquation(contextId, equation).then((data) => {
preview.innerHTML = data.content;
notifyFilter(preview);The Atto plugin did the same through lib/editor/atto/plugins/equation/ajax.php, which echoed the filtered text, and its _loadPreview() handler inserted the response with setHTML(). filter_manager::filter_text() only applies the site's text filters and does not clean the HTML, so markup placed inside an equation could reach the preview unchanged and the browser would run any script in it.
A user who can save text containing such an equation where another user will later edit it, or who can get another user to paste it into an editor, can make script run in that user's browser when they open the equation in the formula editor. The script runs with the victim's session, so a teacher or administrator who previews the equation can be made to perform actions in Moodle on the attacker's behalf. CVSS rates the issue as requiring a low-privileged account and user interaction.
The fix adds a striptags option to both server endpoints and has both editors set it when they request a preview. When it is set, the server removes all HTML tags with PARAM_NOTAGS before running the filters:
// Strip all HTML tags before filtering the text (avoiding XSS risk).
if ($striptags) {
$content = clean_param($content, PARAM_NOTAGS);
}The Atto ajax.php endpoint applies the same clean_param($text, PARAM_NOTAGS) call, and the prebuilt JavaScript for both plugins was updated to send the new parameter.
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.22, 4.4.12, 4.5.8, 5.0.4, 5.1.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
- Aleksey Solovev (Positive Technologies) (finder)