From e562966d46c338b76dfa86c22991cc89a9d14772 Mon Sep 17 00:00:00 2001 From: Shrihari Mahabal Date: Mon, 6 Apr 2026 17:25:36 +0530 Subject: [PATCH] fix(security): escape html in invalidation warnings --- frappe/core/doctype/data_import/importer.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/frappe/core/doctype/data_import/importer.py b/frappe/core/doctype/data_import/importer.py index 3ddc070fc5..c356da366f 100644 --- a/frappe/core/doctype/data_import/importer.py +++ b/frappe/core/doctype/data_import/importer.py @@ -13,6 +13,7 @@ from frappe.core.doctype.version.version import get_diff from frappe.model import no_value_fields from frappe.utils import cint, cstr, duration_to_seconds, flt, update_progress_bar from frappe.utils.csvutils import get_csv_content_from_google_sheets, read_csv_content +from frappe.utils.data import escape_html from frappe.utils.xlsxutils import ( read_xls_file_from_attached_file, read_xlsx_file_from_attached_file, @@ -727,7 +728,9 @@ class Row: elif df.fieldtype == "Link": exists = self.link_exists(value, df) if not exists: - msg = _("Value {0} missing for {1}").format(frappe.bold(value), frappe.bold(df.options)) + msg = _("Value {0} missing for {1}").format( + frappe.bold(escape_html(cstr(value))), frappe.bold(df.options) + ) self.warnings.append( { "row": self.row_number, @@ -746,7 +749,8 @@ class Row: "col": col.column_number, "field": df_as_json(df), "message": _("Value {0} must in {1} format").format( - frappe.bold(value), frappe.bold(get_user_format(col.date_format)) + frappe.bold(escape_html(cstr(value))), + frappe.bold(get_user_format(col.date_format)), ), } ) @@ -761,7 +765,8 @@ class Row: "col": col.column_number, "field": df_as_json(df), "message": _("Value {0} must in {1} format").format( - frappe.bold(value), frappe.bold(get_user_format(col.date_format)) + frappe.bold(escape_html(cstr(value))), + frappe.bold(get_user_format(col.date_format)), ), } ) @@ -774,7 +779,7 @@ class Row: "col": col.column_number, "field": df_as_json(df), "message": _("Value {0} must be in the valid duration format: d h m s").format( - frappe.bold(value) + frappe.bold(escape_html(cstr(value))) ), } ) @@ -1045,7 +1050,7 @@ class Column: ] not_exists = list(set(values) - set(exists)) if not_exists: - missing_values = ", ".join(not_exists) + missing_values = ", ".join(escape_html(v) for v in not_exists) message = _("The following values do not exist for {0}: {1}") self.warnings.append( { @@ -1088,7 +1093,7 @@ class Column: invalid = values - set(options) if invalid: valid_values = ", ".join(frappe.bold(o) for o in options) - invalid_values = ", ".join(frappe.bold(i) for i in invalid) + invalid_values = ", ".join(frappe.bold(escape_html(i)) for i in invalid) message = _("The following values are invalid: {0}. Values must be one of {1}") self.warnings.append( {