From f3150c3495453067aeaf6700932ed6441911caa2 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Tue, 10 Nov 2026 21:19:53 -0800 Subject: [PATCH] admin: escape file properties before rendering the modal (#12548) * admin: escape file properties before rendering the modal The Properties modal concatenated the entry name, path, MIME type and extended attributes into HTML, so object metadata written over S3 could inject markup into the admin page. Co-Authored-By: Claude Opus 5.5 * admin: keep every property key when escaping Co-Authored-By: Claude Opus 5.5 --------- Co-authored-by: Claude Opus 5.5 --- weed/admin/view/app/file_browser.templ | 15 ++++++++++++++- weed/admin/view/app/file_browser_templ.go | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/weed/admin/view/app/file_browser.templ b/weed/admin/view/app/file_browser.templ index 24db7870df..cda7bca7fa 100644 --- a/weed/admin/view/app/file_browser.templ +++ b/weed/admin/view/app/file_browser.templ @@ -434,7 +434,7 @@ templ FileBrowser(data dash.FileBrowserData) { if (data.error) { showAlert('Error loading file properties: ' + data.error, 'error'); } else { - displayFileProperties(data); + displayFileProperties(escapeProperties(data)); } }) .catch(error => { @@ -443,6 +443,19 @@ templ FileBrowser(data dash.FileBrowserData) { }); } + function escapeProperties(value) { + if (typeof value === 'string') { + return escapeHtml(value); + } + if (Array.isArray(value)) { + return value.map(escapeProperties); + } + if (value && typeof value === 'object') { + return Object.fromEntries(Object.entries(value).map(([key, item]) => [escapeHtml(key), escapeProperties(item)])); + } + return value; + } + function displayFileProperties(data) { // Create a comprehensive modal for file properties const modalHtml = '
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "\">
0%
Preparing upload...
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err }