From 742e0e16cf943cf4b411ba768c7be8cb95c1a0fd Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Thu, 6 Aug 2026 08:53:46 +0530 Subject: [PATCH] fix: XSS through unescaped work order name in shop floor view (#57826) --- erpnext/public/js/shop_floor/shop_floor.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/erpnext/public/js/shop_floor/shop_floor.js b/erpnext/public/js/shop_floor/shop_floor.js index a595102c004..4495c825169 100644 --- a/erpnext/public/js/shop_floor/shop_floor.js +++ b/erpnext/public/js/shop_floor/shop_floor.js @@ -356,7 +356,7 @@ class ShopFloor { // Hero image = the current operation's workstation. No item-image fallback — when the // workstation has no image uploaded we show its initials, never the product image. const image = wo.workstation_image - ? `` + ? `` : `${frappe.get_abbr(wo.workstation_name || item, 2)}`; const workstation_line = wo.workstation_name @@ -370,7 +370,9 @@ class ShopFloor { const wip_pct = Math.min(cint(wo.per_in_progress), 100 - done_pct); return ` -
+
${image}
@@ -378,7 +380,9 @@ class ShopFloor { ${workstation_line}
@@ -405,7 +409,7 @@ class ShopFloor { this.board_container .find(".sf-wo-card") .removeClass("sf-selected") - .filter(`[data-name="${name}"]`) + .filter(`[data-name="${$.escapeSelector(name)}"]`) .addClass("sf-selected"); // The detail pane reuses the operator rendering for a single work order. this.detail_container.html(` @@ -414,7 +418,9 @@ class ShopFloor { "Back" )} (Esc) ${frappe.utils.escape_html(name)} - ${__("Open")} + ${__( + "Open" + )}
`); @@ -1235,7 +1241,7 @@ class ShopFloor { const pad = (n) => (n < 10 ? "0" + n : String(n)); const scope = $container || this.wrapper; - const timer = scope.find(`.mes-job-timer[data-job-card="${jc_name}"]`); + const timer = scope.find(`.mes-job-timer[data-job-card="${$.escapeSelector(jc_name)}"]`); timer.find(".h").text(pad(h)); timer.find(".m").text(pad(m)); timer.find(".s").text(pad(s));