The vulnerability (CVE-2025-48494) is a stored Cross-Site Scripting (XSS) issue in Gokapi, triggered by uploading a file with a malicious filename containing JavaScript. When the list of uploads is displayed or an individual file's details are shown (e.g., in an edit modal), the embedded script from the filename is parsed and executed by the browser.
The analysis of the patch commit 343cc566cfd7f4efcd522c92371561d494aed6b0 reveals several JavaScript functions that were modified to prevent this XSS.
The core of the vulnerability lies in these functions taking user-supplied data (the filename, or data derived from it like a file ID) and inserting it into the DOM using unsafe methods like element.innerHTML = ... or potentially unsafe third-party library methods like datatable.cell().data() if they render HTML content.
Key vulnerable functions identified are:
addRow (in admin_ui_upload.js): This function is central to displaying the list of uploaded files. It was vulnerable because it constructed parts of the table row HTML using string concatenation and innerHTML (e.g., for cellUrl using item.Id which could be derived from the filename, and for cellButtons which constructed an onclick handler passing the raw filename to showEditModal). The patch refactored this to use safer DOM creation methods and introduced sanitizeId() for item.Id.
showEditModal (in admin_ui_upload.js): This function, called when editing a file, directly used innerHTML to display the filename in a modal, making it a clear XSS vector. The patch changed this to use innerText.
decryptFileEntry (in end2end_admin.js): For end-to-end encrypted files, this function updates the filename in the UI. It previously used datatable.cell().data(filename), which could render HTML if the filename was malicious. The patch changed this to use the safer textContent property.
displayError (in end2end_admin.js): This function used to display error messages. If an error could be triggered that incorporated the malicious filename, this would also be an XSS vector. The patch changed this to safer DOM manipulation.