fix: escape user-controlled fields in admin/users innerHTML to prevent stored XSS

u.name and u.email are stored user input and were interpolated raw into
tbody.innerHTML. Added esc() helper and applied to name, email, and role
display string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
GuavaPopper
2026-06-03 13:53:01 +07:00
parent 8476c5d643
commit c1c1fae93c
+7 -3
View File
@@ -240,6 +240,10 @@
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
let usersData = [];
function esc(s) {
return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
}
document.addEventListener('DOMContentLoaded', loadUsers);
async function loadUsers() {
@@ -285,11 +289,11 @@
tbody.innerHTML = usersData.length ? usersData.map((u, i) => `
<tr>
<td class="text-xs font-bold opacity-30">${i + 1}</td>
<td><div class="font-bold">${u.name}</div></td>
<td class="text-sm opacity-70">${u.email}</td>
<td><div class="font-bold">${esc(u.name)}</div></td>
<td class="text-sm opacity-70">${esc(u.email)}</td>
<td>
<span class="badge badge-sm ${roleBadge[u.role] || 'badge-neutral'} badge-outline capitalize">
${roleLabels[u.role] || u.role}
${esc(roleLabels[u.role] || u.role)}
</span>
</td>
<td class="text-center">