From 3ac98b7bc36485d95b759c159f992019a1915924 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 09:17:07 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[HIGH]=20Fi?= =?UTF-8?q?x=20XSS=20vulnerability=20in=20confirm=20dialog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated `showConfirmDialog` to use `textContent` instead of `innerHTML` when injecting user-provided string variables into the DOM, mitigating the risk of Cross-Site Scripting (XSS). Co-authored-by: thirdeyenation <133812267+thirdeyenation@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ webui/js/confirmDialog.js | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000000..b6927e6e31 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-05-24 - Cross-Site Scripting (XSS) in UI Modals +**Vulnerability:** The confirm dialog component used `innerHTML` with string interpolation for dynamic arguments like `title`, `message`, `confirmText`, and `cancelText`, introducing a Cross-Site Scripting (XSS) vulnerability. +**Learning:** Reusable UI components that accept arbitrary text arguments are prone to XSS if they construct DOM elements using template literals and `innerHTML` instead of dynamically setting properties like `textContent` after DOM construction. +**Prevention:** Avoid `innerHTML` when rendering user-provided or dynamically constructed text variables in frontend modules. Render the skeleton HTML first, select the nodes, and populate their content using `textContent`. diff --git a/webui/js/confirmDialog.js b/webui/js/confirmDialog.js index 6289af608b..a7864de8fb 100644 --- a/webui/js/confirmDialog.js +++ b/webui/js/confirmDialog.js @@ -31,12 +31,12 @@ export function showConfirmDialog(options) { dialog.innerHTML = `
${typeConfig.icon} - ${title} +
-
${message}
+
`; @@ -48,6 +48,11 @@ export function showConfirmDialog(options) { const footerElement = dialog.querySelector('.confirm-dialog-footer'); const cancelButton = dialog.querySelector('.confirm-dialog-cancel'); const confirmButton = dialog.querySelector('.confirm-dialog-confirm'); + + titleElement.textContent = title; + bodyElement.textContent = message; + cancelButton.textContent = cancelText; + confirmButton.textContent = confirmText; let isClosed = false; // Show with animation