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:
@@ -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 => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[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">
|
||||
|
||||
Reference in New Issue
Block a user