Full Disclosure mailing list archives

SCHUTZWERK-SA-2024-007: Stored Cross-Site Scripting via file upload in H5P module (h5p-nodejs-library) of Lumi Education


From: David Brown via Fulldisclosure <fulldisclosure () seclists org>
Date: Wed, 9 Sep 2026 08:21:46 +0200

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

A stored cross-site scripting (XSS) vulnerability has been identified in the H5P module h5p-nodejs-library by Lumi Education UG in versions up to and including 10.0.4. The library allows users to upload H5P content that contains malicious JavaScript. This code is then executed in the browsers of other users who view the affected H5P content.

Metadata
========

- - Affected product: h5p-nodejs-library
- - Affected version: All versions up to and including 10.0.4 (no complete fix available at
  the time of publication)
- - Vendor: Lumi Education UG
- - Problem type(s):
- CWE-79 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
    - CWE-20 Improper Input Validation
- - CVE ID: CVE-2025-7062
- - CVE URL: https://www.cve.org/CVERecord?id=CVE-2025-7062
- - CVSS 4.0 score: 5.2
- - Advisory URL: https://www.schutzwerk.com/en/blog/schutzwerk-sa-2024-007/

Details
=======

H5P content is distributed as ZIP archives. When unpacked, an archive contains a folder structure whose files define the content of the H5P object. Images embedded in an H5P content type are stored in the content/images/ subfolder and referenced from the
content/content.json file.

For this analysis, an SVG image file named circle.svg was crafted with the following
content:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   version="1.1"
   id="svg2"
   sodipodi:docname="circle.svg"
   xmlns="http://www.w3.org/2000/svg";
   xmlns:svg="http://www.w3.org/2000/svg";>
  <script>alert("XSS Test");</script>
  <script>alert(document.cookie);</script>
  <circle
style="fill:#666666;stroke:#808080;stroke-width:4.40315;stop-color:#000000"
     id="path233"
     cx="98.428535"
     cy="68.415733"
     r="54.194405" />
</svg>


Besides rendering a circle, the file contains two lines of JavaScript: the first opens a dialog showing the text "XSS Test", and the second displays the contents of the session cookie. The file is placed in the content/images/ subfolder and referenced in
content/content.json as follows:

{
  "media": {
    "type": {
      "params": {
        "decorative": false,
        "contentName": "Image",
        "expandImage": "Expand Image",
        "minimizeImage": "Minimize Image",
        "file": {
          "path": "images/circle.svg",
          "mime": "image/svg+xml",
[...]


The object's folders and files are then repacked with the ZIP algorithm and saved locally as TrueFalse_Title_malicious.h5p. Using the upload function of the H5P framework, the attacker stores this file on the server. Running the H5P object on the server does not execute the embedded JavaScript on its own. However, opening the SVG graphic in a separate browser tab executes the contained script, and the session cookie is shown in a dialog
window.

Risk
====

Where users can create and share H5P objects, this vulnerability can be used to hijack other users' accounts, for example through phishing with injected fake login forms. An attacker can also track a victim's actions within the application and perform actions on their behalf. If an administrative user is targeted, the attacker may be able to escalate privileges further, for instance by creating new administrative users or assigning
additional roles to existing ones.

Solution/Mitigation
===================

At the time of publication, no release fully prevents the upload and execution of files that contain JavaScript. Version 10.0.4 removes the SVG file extension from the default content allowlist, but it still identifies permitted files by their filename extension alone. An attacker can therefore upload a file with malicious JavaScript content under an
allowed extension, such as XML, and have it executed.

Until a complete fix is available, operators should not rely on extension-based filtering alone. Uploaded files should be validated and sanitized based on their actual content rather than their filename. For SVG uploads specifically, the library's SVG file sanitization[0] can be enabled, which uses DOMPurify to remove malicious script content
from uploaded files.

Timeline
========

- - 2024-10-23 Vulnerability discovered
- - 2024-11-08 Initial contact attempt, email sent to c@lumi.education
- - 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-25 First exchange between Lumi and the team of developers who use the H5P
  framework in their project
- - 2025-03-07 Release of h5p-nodejs-library v10.0.4
(https://github.com/Lumieducation/H5P-Nodejs-library/releases/tag/v10.0.4), which introduces an interface for file content sanitizers and an allowlist of file types permitted in H5P modules based on their filename extension. The SVG file extension is
  excluded.
- - 2025-09-18 Identified that the allowlist approach does not prevent the upload of files
  with XSS content that is executed after loading
- - 2025-09-18 Sent email to security@lumi.education with an update on the finding and
  received a response the same day
- - 2025-09-18 Received a response from a developer working on Lumi Education - - 2025-09-22 Video call with a developer working on Lumi Education. Received a commitment that an updated version including a fix should be ready within a few weeks
- - 2025-09-23 Exchange with the developer on details of the fix
- - 2025-09-24 Exchange with the developer on details of the fix
- - 2025-10-20 Requested a status update on the patch from the developer. No response
  received.
- - 2025-11-14 Requested a status update on the patch from the developer. No response
  received.
- - 2025-11-20 Requested a status update on the patch from the developer. No response
  received.
- - 2025-11-26 Informed the business contact about the current status and recommended measures for the framework developers to implement. Publication delayed for undisclosed
  reasons.
- - 2026-09-09 Advisory released

Credits
=======

The vulnerability was discovered by Florian Schmid of SCHUTZWERK GmbH.

Footnotes
=========

[0] https://github.com/Lumieducation/H5P-Nodejs-library/blob/v10.0.4/docs/packages/h5p-svg-sanitizer.md
-----BEGIN PGP SIGNATURE-----

iQJOBAEBCgA4FiEEgLsg7Oj/wY3LSF87GrXfkTIXLrsFAmqg+lcaHGFkdmlzb3Jp
ZXNAc2NodXR6d2Vyay5jb20ACgkQGrXfkTIXLrtd7hAAt/fhW+fVFc5JlaevO/pu
OlVkBwTQjZcX3qxZRgAVbV0HuwLPh/YTgiCLjidVfAIzVJbQSU0eDKrt3G4t82Te
rhXkY0ctzwOGya3nIwEI/I/QpKH/W75NDRL2ewI7iiJB8guQWBZzb7cFSAOoeNMi
nUkdo35BwqNr+TccXjNVwnlsXHTdW1RbzIwE9yUHujjT7vkUNcoDftPoguBjRsG1
OSlcjqDvMPNkApQiXWniwz0wY/6WYQgt96RB96Wl0uJLMazLgtgVgso7rcZW3Sjd
pi1yHYD3f+/ch9iPQBFq0SIcnH+kJC2oNXypM0VDjtCdNt+KveiBnbJsl9zSTdHj
ylllLxE58bkVuONcInxHeo6MSRBGLAJ0Hiq1uHFeQuya6L53Lr5Nb65IVQJe3f2T
x56Gwhs+xhGr/hd0k/CmaRXxApFm8HPLr1M3uCPrJXzT6THBZxcuWcJr9WXUj1ZT
WNBHlf06aK8SWHtVDugeTJK38N/Esetc9Z8XY1PdiVp4ab0qJMi9w4YWtJgeeL2d
TbIObBSI0i9OR1GdrXvVKB6F/PvpuTHupCMR+2yI/mMEzb2KgDQiZpEqh1qOy01u
B+7bH2qwlnZrz6SL0vfZCwZ/KJbKf+/hSq+3V4XcK415cQsUZbT07y5qxUZIK/wE
npRisQyYZ+Z+QaMWsSxMf7c=
=pVF/
-----END PGP SIGNATURE-----


--
SCHUTZWERK GmbH, Pfarrer-Weiß-Weg 12, 89077 Ulm, Germany
Zertifiziert / Certified ISO 27001, 9001 and TISAX

Phone +49 731 977 191 0

advisories () schutzwerk com / www.schutzwerk.com

Geschäftsführer / Managing Directors:
Jakob Pietzka, Michael Schäfer

Amtsgericht Ulm /  HRB 727391
Datenschutz / Data Protection www.schutzwerk.com/datenschutz

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/

Current thread: