Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2025-52896

CVE-2025-52896: Frappe Framework XSS Vulnerability

CVE-2025-52896 is a cross-site scripting flaw in Frappe Framework that allows authenticated users to upload malicious files via Data Import. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2025-52896 Overview

CVE-2025-52896 is a stored cross-site scripting (XSS) vulnerability in the Frappe full-stack web application framework. Authenticated users can upload maliciously crafted files through the Data Import feature, injecting script content that executes in other users' browsers when preview data or filenames render in the UI. The flaw affects Frappe versions prior to 14.94.2 and 15.57.0, and is tracked under [CWE-79]. Frappe published a fix in versions 14.94.2 and 15.57.0 through GHSA-hv29-66qg-2v6p.

Critical Impact

Authenticated attackers can execute arbitrary JavaScript in the context of any user viewing a data import preview or attached file, enabling session theft, account takeover, and privileged action abuse within the Frappe application.

Affected Products

  • Frappe framework versions prior to 14.94.2
  • Frappe framework versions prior to 15.57.0
  • Applications built on Frappe using the Data Import module (including ERPNext deployments)

Discovery Timeline

  • 2025-06-30 - CVE-2025-52896 published to NVD
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2025-52896

Vulnerability Analysis

The vulnerability lives in the client-side rendering path of the Frappe Data Import feature. When an authenticated user uploads a file for import, the framework renders a preview of the parsed rows and the file's attachment metadata in the browser. Prior to the patch, the code inserted string cell values and filenames directly into the DOM using jQuery .html() and template literals without escaping HTML entities.

An attacker with import permissions can craft a CSV or spreadsheet containing HTML or JavaScript in a cell value, or upload a file whose name contains an HTML payload. When another user, including an administrator, opens the import record, the injected markup executes in their session context. Because Frappe stores uploaded files and import records server-side, the payload persists across sessions, making this a stored XSS rather than a reflected one.

Root Cause

The root cause is missing output sanitization in two client modules: frappe/public/js/frappe/data_import/import_preview.js and frappe/public/js/frappe/form/controls/attach.js. Neither location routed user-controlled strings through the framework's frappe.utils.xss_sanitise helper before writing them into the DOM.

Attack Vector

Exploitation requires an authenticated account with Data Import privileges. The attacker uploads a file whose cell contents or filename embed an HTML/JavaScript payload, then waits for another authenticated user to open the preview or view the attachment link. Delivery is fully network-based over the standard Frappe web interface.

javascript
// Patch: frappe/public/js/frappe/data_import/import_preview.js
				if (cell == null) {
					return "";
				}
+
+				if (typeof cell === "string") {
+					cell = frappe.utils.xss_sanitise(cell);
+				}
				return cell;
			});
		});

Source: frappe commit 152fd09

javascript
// Patch: frappe/public/js/frappe/form/controls/attach.js
				this.$value
					.toggle(true)
					.find(".attached-file-link")
-					.html(filename || this.value)
+					.html(frappe.utils.xss_sanitise(filename || this.value))
					.attr("href", dataurl || this.value);
			} else {
				this.$wrapper.html(`
					  <div class="attached-file flex justify-between align-center">
						<div class="ellipsis">
-						  <a href="${dataurl || this.value}" target="_blank">${filename || this.value}</a>
+						  <a href="${dataurl || this.value}" target="_blank">${frappe.utils.xss_sanitise(
+					filename || this.value
+				)}</a>
						</div>
					  </div>
				`);

Source: frappe commit f11c53d

The fix wraps both the parsed cell values and the attachment filename in the frappe.utils.xss_sanitise helper before DOM insertion.

Detection Methods for CVE-2025-52896

Indicators of Compromise

  • Uploaded Data Import files whose cell values contain <script, onerror=, onload=, or javascript: substrings.
  • File attachments whose stored filenames contain HTML tag characters (<, >) or event-handler attributes.
  • Frappe audit log entries showing Data Import creation immediately followed by preview access from a different, higher-privileged user.

Detection Strategies

  • Scan the Frappe file storage directory and tabFile records for filenames containing angle brackets or JavaScript URI schemes.
  • Query the Data Import doctype for rows whose parsed content includes common XSS sink patterns and review the associated uploader.
  • Inspect web server access logs for POSTs to /api/method/upload_file and /api/method/frappe.core.doctype.data_import.data_import.* originating from low-privilege accounts.

Monitoring Recommendations

  • Alert on Data Import activity performed by non-administrative roles, especially when followed by admin viewing the same record.
  • Monitor browser Content Security Policy (CSP) violation reports for inline script execution on /app/data-import/* routes.
  • Track version strings returned by Frappe's /api/method/frappe.utils.change_log.get_versions endpoint to confirm patched builds are deployed across environments.

How to Mitigate CVE-2025-52896

Immediate Actions Required

  • Upgrade Frappe to version 14.94.2 or 15.57.0, or any later release on those branches.
  • Audit Data Import records and stored files created before the upgrade for HTML or JavaScript content, and delete or sanitize suspicious entries.
  • Review which roles hold the Data Import permission and revoke access from users who do not require it.

Patch Information

The fix is delivered in Frappe 14.94.2 and 15.57.0 through pull request #31483, with the backport merged via commits 152fd09 and f11c53d. Both patches route untrusted strings through frappe.utils.xss_sanitise before rendering. Full details are in the advisory GHSA-hv29-66qg-2v6p.

Workarounds

  • No workarounds are available; upgrading to a patched version is the only supported remediation per the vendor advisory.
  • As a defense-in-depth measure until patching, restrict the Data Import role to trusted administrators and enforce a strict Content Security Policy that disallows inline scripts on Frappe admin routes.
bash
# Upgrade Frappe using the bench CLI
bench switch-to-branch version-15 frappe --upgrade
bench update --patch
bench --site all migrate
bench restart

# Verify the installed version meets the patched baseline
bench version | grep frappe

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.