Rocket LMS 1.9 - Persistent Cross Site Scripting (XSS)
# Title: Rocket LMS 1.9 - Persistent Cross Site Scripting (XSS)
# Date: 04/16/2024
# Exploit Author: Sergio Medeiros
# Vendor Homepage: https://codecanyon.net/item/rocket-lms-learning-management-academy-script/33120735
# Software Link: https://lms.rocket-soft.org
# Version: 1.9
# Tested on Firefox and Chrome Browsers
# Patched Version: Patch Pending
# Category: Web Application
# CVE: CVE-2024-34241
# Exploit link: https://grumpz.net/cve-2024-34241-a-step-by-step-discovery-guide
# PoC:
In order to exploit this systemic stored XSS vulnerability, identify theareas in the web application which has a WYSIWIG editor used, for example, the create/edit course description section.
Input random text in the description section, and create the course while intercepting the request with BurpSuite or your preferred proxy of choice.
In the *description* parameter or the associated parameter that is handling the user input related to the WYSIWIG editor, input the following payload and then issue the request:
<details/open/ontoggle=prompt(origin)> Rocket LMS 1.9 — Persistent Cross‑Site Scripting (CVE‑2024‑34241)
This article explains the persistent Cross‑Site Scripting (XSS) issue reported against Rocket LMS 1.9 (CVE‑2024‑34241), why it matters, how to detect and mitigate it, and development best practices to prevent similar vulnerabilities. Content focuses on defensive measures, secure coding patterns, and incident handling rather than exploitation steps.
Overview
Persistent (stored) XSS occurs when an application accepts untrusted HTML or text from a user, stores it on the server (for example, in a course description), and later renders that content into other users’ browsers without adequate sanitization or context‑aware encoding. In learning management systems that use WYSIWYG editors, stored XSS is a common risk because editors allow rich HTML input.
Affected components and risk profile
- Likely affected areas: WYSIWYG editor fields such as course descriptions, lesson content, announcements, and user profiles where HTML input can be saved and displayed to other users.
- Impact: An attacker can store malicious markup that executes in the browsers of instructors, students, or administrators. This may lead to session theft, unauthorized actions, information disclosure, malware delivery, or account takeover depending on privileges.
- Exploitability: Stored XSS is generally high‑impact because it does not require the target to visit an attacker‑controlled site — the vulnerable application itself serves the payload.
Indicators of compromise and detection
- Unusual JavaScript or HTML appearing in pages originating from user editable fields.
- Unexpected alerts, redirections, or cookie leaks when viewing content created by other users.
- Web application logs showing submissions with suspicious HTML fragments or unusual attributes in WYSIWYG payloads.
- Automated scans that flag persistent XSS in stored content endpoints (create/edit/display flows).
Short table: vulnerability metadata
| Product | Version | CVE | Status |
|---|---|---|---|
| Rocket LMS | 1.9 | CVE‑2024‑34241 | Patch Pending / Vendor Advisory Recommended |
Mitigation and remediation guidance
Fixing stored XSS requires a layered approach: sanitize and validate input, use context‑aware output encoding, apply strong Content‑Security‑Policy (CSP), and restrict privileges. Below are practical steps teams can implement immediately.
- Apply vendor patch: When a vendor patch is available, test and deploy it promptly via your normal change control process.
- Whitelist HTML in WYSIWYG: Configure WYSIWYG editors to allow only a minimal set of safe tags and attributes. Disable script execution, inline event handlers (onclick, onerror), style attributes that allow expression(), and disallow potentially dangerous tags like <script>, <iframe>, <object>, <embed>.
- Server‑side sanitization: Always enforce sanitization on the server side in addition to any client restrictions. Client‑side filtering alone can be bypassed.
- Context‑aware output encoding: When rendering data into HTML, attributes, JavaScript, or CSS contexts, use appropriate encoding functions rather than inserting raw HTML.
- Implement CSP: Use Content‑Security‑Policy to limit script sources and block inline scripts where feasible. CSP reduces the impact of XSS even if an attack payload gets stored.
- Harden session cookies: Use HttpOnly and Secure flags and consider SameSite to reduce cookie theft risk via script injection.
Secure coding examples (defensive)
Below are safe examples showing server‑side sanitization and output encoding. These examples are defensive patterns — they do not provide exploit payloads.
/* PHP example using HTMLPurifier (recommended for server-side sanitization) */require_once 'htmlpurifier/library/HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
/* Allow only a limited set of tags and attributes */$config->set('HTML.Allowed', 'p,b,i,em,strong,a[href|title|rel],ul,ol,li,br');
$config->set('URI.SafeIframeRegexp', null); /* disable iframes */$purifier = new HTMLPurifier($config);
/* Purify user input before saving in DB */$raw = $_POST['description'] ?? '';
$safe_description = $purifier->purify($raw);
/* Store $safe_description in the database */Explanation: This PHP snippet uses HTMLPurifier to sanitize the incoming HTML. The configuration whitelists only simple formatting tags and anchor attributes, removing scripts, event handlers, and disallowed attributes. Purification occurs on the server side before persisting to storage, preventing stored malicious markup.
/* Output encoding when printing non-HTML data */echo htmlspecialchars($some_text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
Explanation: htmlspecialchars converts special characters to HTML entities, preventing injected markup from being interpreted by the browser. Use this for any user input that is not intended to be interpreted as HTML.
/* Node.js example (server-side) using DOMPurify via jsdom */const { JSDOM } = require('jsdom');
const createDOMPurify = require('dompurify');
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
/* Configure allowed tags if needed */const clean = DOMPurify.sanitize(unsafeHtml, {
ALLOWED_TAGS: ['p','b','i','em','strong','a','ul','ol','li','br'],
ALLOWED_ATTR: ['href','title','rel']
});
/* Save 'clean' to DB */Explanation: DOMPurify used on the server side (with JSDOM) strips dangerous tags and attributes. As with the PHP example, sanitize and whitelist allowable elements before persisting content.
Content‑Security‑Policy (CSP) example
/* Example HTTP header */Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self';
Explanation: This CSP header allows scripts only from the same origin and blocks plugin content and framing. CSP is not a replacement for sanitization, but it significantly reduces attack surface by blocking injection attempts that rely on external scripts or inline execution.
Operational recommendations
- Perform a focused review of all places that accept rich text/WYSIWYG input (courses, lessons, announcements, profile bios) and apply server‑side sanitization uniformly.
- Add automated tests that attempt a variety of malicious inputs (as negative tests) to verify sanitizers consistently remove dangerous markup.
- Harden authentication and session management — least privilege, short session lifetime for admin interfaces, and multi‑factor authentication for privileged users.
- Log submissions containing HTML and review suspicious submissions in logs or implement automated alerts for suspicious attribute patterns.
- Coordinate disclosure with the vendor and apply vendor fixes; if a patch is not yet available, implement the mitigations above and restrict editor capabilities until a fix is deployed.
Incident response and disclosure
If you discover evidence that stored XSS has been exploited in your environment:
- Contain by disabling or restricting the affected input widgets (e.g., turn WYSIWYG editors into plain text or remove publish permissions temporarily).
- Identify and clean any stored malicious records; preserve forensic copies before modification.
- Rotate credentials and sessions for impacted users, and invalidate active sessions where appropriate.
- Notify affected users and regulators as required by policy and law, and apply the vendor patch once available.
Developer best practices to prevent XSS
- Adopt defense‑in‑depth: input validation, server‑side sanitization, output encoding, and CSP.
- Prefer templating engines and frameworks that auto‑escape content for HTML contexts; apply context‑specific escaping for attributes, JavaScript, or CSS contexts.
- Minimize allowed HTML features in rich editors; consider offering markdown with strict rendering as an alternative to free HTML input.
- Maintain a security testing regimen that includes static analysis, dependency checks, and dynamic scanning for XSS and related issues.
Summary
Stored XSS in LMS platforms like Rocket LMS can have severe consequences because content authored by one user can execute in other users’ browsers. The correct response is to sanitize and validate inputs on the server, perform context‑aware output encoding, harden HTTP headers (CSP, cookie flags), and deploy vendor patches. These measures, together with secure development practices and monitoring, reduce the risk and impact of persistent XSS vulnerabilities.