fix: Sanitize filenames and directory paths to prevent XSS

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
2026-05-18 15:55:40 +00:00
parent ca5131f497
commit d00e1dceeb

View File

@@ -483,6 +483,15 @@
const filesTBody = document.getElementById('filesTBody');
let DIRS = [];
function escapeHtml(text) {
return String(text)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
function humanSize(bytes){
if (!bytes) return '0 B';
const k = 1024, sizes = ['B','KB','MB','GB','TB'];
@@ -509,7 +518,7 @@
const modified = `<span title="${new Date(dir.modified).toLocaleString()}">${fmtDayMonthForFiles(dir.modified)}</span>`;
return `
<tr class="border-b dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-900/50 cursor-pointer" data-path-b64="${dir.path_b64}">
<td class="py-2">${dir.path}</td>
<td class="py-2">${escapeHtml(dir.path)}</td>
<td class="py-2">${dir.file_count}</td>
<td class="py-2">${humanSize(dir.total_size)}</td>
<td class="py-2">${modified}</td>
@@ -545,12 +554,13 @@
${files.length ? `<div class="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8 gap-4">` + files.map(it => {
const thumbUrl = it.is_image ? `/api/files/thumb/${it.path_b64}` : '';
const fullUrl = `/api/files/full/${it.path_b64}`;
return `<a href="${fullUrl}" target="_blank" title="${it.name.replaceAll('"','&quot;')}\n${humanSize(it.size)}" class="group relative aspect-square rounded-lg overflow-hidden bg-gray-100 dark:bg-gray-800 flex items-center justify-center">
const safeName = escapeHtml(it.name);
return `<a href="${fullUrl}" target="_blank" title="${safeName}\n${humanSize(it.size)}" class="group relative aspect-square rounded-lg overflow-hidden bg-gray-100 dark:bg-gray-800 flex items-center justify-center">
${it.is_image ?
`<img src="${thumbUrl}" class="w-full h-full object-cover" loading="lazy"/>` :
`<svg xmlns="http://www.w3.org/2000/svg" class="w-12 h-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" /></svg>`
}
<div class="absolute bottom-0 left-0 right-0 bg-black/50 text-white text-xs p-1 truncate pointer-events-none">${it.name}</div>
<div class="absolute bottom-0 left-0 right-0 bg-black/50 text-white text-xs p-1 truncate pointer-events-none">${safeName}</div>
</a>`
}).join('') + `</div>` : '<div class="text-sm text-gray-500">No files in this directory.</div>'}
</div>