From 00ec6888c5fc0fe365c65a1a8d6a24f299303af8 Mon Sep 17 00:00:00 2001 From: Christian Krakau-Louis Date: Sat, 30 May 2026 07:36:58 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[HIGH]=20Fi?= =?UTF-8?q?x=20DOM-based=20XSS=20in=20upload.js=20(#900)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🛡️ Sentinel: [HIGH] Fix DOM-based XSS in upload.js Added `_escapeHtml` function to sanitize user-controlled `file.name` before interpolating it into the `row.innerHTML` payload, preventing malicious file names from executing XSS during uploads. Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> * Tighten XSS fix PR payload --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> Co-authored-by: Christian Krakau-Louis --- frontend/static/js/upload.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/static/js/upload.js b/frontend/static/js/upload.js index b8ecd62a..539cd4c9 100644 --- a/frontend/static/js/upload.js +++ b/frontend/static/js/upload.js @@ -293,13 +293,24 @@ function processFiles(files, progressContainer, statusMessage) { updateStatus(); } + function _escapeHtml(str) { + if (!str) return ''; + return String(str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + // Pre-create one progress row per file. const queueItems = fileArray.map((file) => { const row = document.createElement('div'); row.className = 'flex flex-col mb-2'; + const safeFileName = _escapeHtml(file.name); row.innerHTML = `
- ${file.name} + ${safeFileName} ${formatFileSize(file.size)}
@@ -546,4 +557,3 @@ function initDragAndDrop(element, progressContainer, statusMessage, options = {} }); } -