From c1c1fae93c7bd1cf5010035232cd874c626669db Mon Sep 17 00:00:00 2001 From: GuavaPopper Date: Wed, 3 Jun 2026 13:53:01 +0700 Subject: [PATCH] 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 --- resources/views/admin/users.blade.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/resources/views/admin/users.blade.php b/resources/views/admin/users.blade.php index 841a2cc..84a59d2 100644 --- a/resources/views/admin/users.blade.php +++ b/resources/views/admin/users.blade.php @@ -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) => ` ${i + 1} -
${u.name}
- ${u.email} +
${esc(u.name)}
+ ${esc(u.email)} - ${roleLabels[u.role] || u.role} + ${esc(roleLabels[u.role] || u.role)}