From 116b04ddc1622e3abf0e851810d6c26e9e211ac6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 03:19:52 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[HIGH]=20Fi?= =?UTF-8?q?x=20XSS=20in=20upload.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added an `_escapeHtml` function to properly sanitize `file.name` before it is dynamically rendered into the DOM using `row.innerHTML`. This mitigates a DOM-based Cross-Site Scripting (XSS) vulnerability. Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ frontend/static/js/upload.js | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index af243c59..7d5fdb58 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -28,3 +28,7 @@ **Vulnerability:** The `/process-url` endpoint used `httpx.AsyncClient(follow_redirects=True)` after validating the initial user-provided URL against SSRF protections. However, it did not validate the target URLs of any subsequent HTTP redirects, allowing an attacker to provide a safe URL that redirects to an internal/private IP, bypassing the security check. **Learning:** Initial URL validation is insufficient when the HTTP client is configured to follow redirects automatically. The client must be explicitly configured to validate every redirect target. **Prevention:** When using `httpx.AsyncClient(follow_redirects=True)` for user-provided URLs, always implement a redirect validator hook function (e.g., using `event_hooks={'response': [validate_redirect]}`) that resolves the `Location` header and passes it through the same SSRF validation logic before the redirect is followed. +## 2026-05-27 - DOM-based XSS in upload.js +**Vulnerability:** The `upload.js` frontend file directly injected the user-controlled `file.name` into a string literal passed to `row.innerHTML`. This allowed a malicious filename (e.g., ``) to execute arbitrary JavaScript in the victim's browser context (DOM-based XSS). +**Learning:** Even internal or local files uploaded by a user can contain malicious filenames. Any data dynamically interpolated into an HTML string that is subsequently rendered via `innerHTML` must be strictly sanitized. +**Prevention:** Implement and apply an HTML escaping function (e.g., `_escapeHtml`) to replace dangerous characters (`&`, `<`, `>`, `"`, `'`) with their corresponding HTML entities before injecting user-controlled data into the DOM. diff --git a/frontend/static/js/upload.js b/frontend/static/js/upload.js index b8ecd62a..ffc1ef5c 100644 --- a/frontend/static/js/upload.js +++ b/frontend/static/js/upload.js @@ -293,13 +293,25 @@ function processFiles(files, progressContainer, statusMessage) { updateStatus(); } + function _escapeHtml(unsafe) { + if (!unsafe) return ''; + return String(unsafe) + .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 = `