Moodle: moodle: cross-site scripting (xss) via improper sanitization of ai prompt responses
Description
A flaw was found in Moodle. This cross-site scripting (XSS) vulnerability, caused by improper sanitization of AI prompt responses, allows attackers to inject malicious HTML or script into web pages. When other users view these compromised pages, their sessions could be stolen, or the user interface could be manipulated.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Moodle suffers from a stored XSS vulnerability due to improper sanitization of AI prompt responses, allowing attackers to inject malicious HTML/script that can steal sessions or manipulate UI.
Vulnerability
Overview
CVE-2025-67849 is a stored cross-site scripting (XSS) vulnerability in Moodle, caused by insufficient sanitization of responses generated by AI prompts. The flaw exists in the aiplacement_courseassist external API, where the generatedcontent field from the AI manager's response was returned directly to the client without proper encoding or filtering [1][2]. This allows an attacker to inject arbitrary HTML or JavaScript that will be rendered when other users view the compromised page.
Exploitation and
Attack Surface
To exploit this vulnerability, an attacker must be able to interact with the AI assistant feature in Moodle and trigger a response containing malicious payload. No authentication is required beyond normal access to the AI chat functionality. The attacker can craft a prompt that leads the AI to return a response with embedded script tags or event handlers. When a victim (e.g., a student or instructor) visits the affected page, the injected script executes in their browser session.
Impact
Successful exploitation can lead to session hijacking, data theft (e.g., cookies, tokens), UI manipulation, or further actions such as performing requests on behalf of the victim. Since the XSS is stored, the malicious content persists across sessions, potentially affecting multiple users.
Mitigation
The issue has been patched in Moodle's commit a3063dcaa44dbe66e60a37cadb33bfadfe4feb03 [3]. The fix applies \core_external\util::format_text() with FORMAT_PLAIN to the generatedcontent before returning it, ensuring that HTML and script tags are properly escaped. Administrators should update their Moodle installations to include this commit or apply the latest security release. No workarounds have been published, but restricting access to the AI assistant feature may reduce exposure.
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
moodle/moodlePackagist | < 4.1.22 | 4.1.22 |
moodle/moodlePackagist | >= 4.4.0-beta, < 4.4.12 | 4.4.12 |
moodle/moodlePackagist | >= 4.5.0-beta, < 4.5.8 | 4.5.8 |
moodle/moodlePackagist | >= 5.0.0-beta, < 5.0.4 | 5.0.4 |
moodle/moodlePackagist | >= 5.1.0-beta, < 5.1.1 | 5.1.1 |
Affected products
2Patches
1a3063dcaa44dMDL-87267 aiplacement_courseassist: Improve response formatting
2 files changed · +4 −2
public/ai/placement/courseassist/classes/external/explain_text.php+2 −1 modified@@ -94,10 +94,11 @@ public static function execute( // Send the action to the AI manager. $manager = \core\di::get(\core_ai\manager::class); $response = $manager->process_action($action); + $generatedcontent = $response->get_response_data()['generatedcontent'] ?? ''; // Return the response. return [ 'success' => $response->get_success(), - 'generatedcontent' => $response->get_response_data()['generatedcontent'] ?? '', + 'generatedcontent' => \core_external\util::format_text($generatedcontent, FORMAT_PLAIN, $contextid)[0], 'finishreason' => $response->get_response_data()['finishreason'] ?? '', 'errorcode' => $response->get_errorcode(), 'error' => $response->get_error(),
public/ai/placement/courseassist/classes/external/summarise_text.php+2 −1 modified@@ -94,10 +94,11 @@ public static function execute( // Send the action to the AI manager. $manager = \core\di::get(\core_ai\manager::class); $response = $manager->process_action($action); + $generatedcontent = $response->get_response_data()['generatedcontent'] ?? ''; // Return the response. return [ 'success' => $response->get_success(), - 'generatedcontent' => $response->get_response_data()['generatedcontent'] ?? '', + 'generatedcontent' => \core_external\util::format_text($generatedcontent, FORMAT_PLAIN, $contextid)[0], 'finishreason' => $response->get_response_data()['finishreason'] ?? '', 'errorcode' => $response->get_errorcode(), 'error' => $response->get_error(),
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-mhf6-pp52-8wqjghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-67849ghsaADVISORY
- access.redhat.com/security/cve/CVE-2025-67849ghsavdb-entryx_refsource_REDHATWEB
- bugzilla.redhat.com/show_bug.cgighsaissue-trackingx_refsource_REDHATWEB
- github.com/moodle/moodle/commit/a3063dcaa44dbe66e60a37cadb33bfadfe4feb03ghsaWEB
- moodle.org/mod/forum/discuss.phpghsaWEB
News mentions
0No linked articles in our index yet.