T09 · Insecure Skill Coding Practices
- Location
src/roundtable/web/viewer.js:419- Finding
Stored Cross-Site Scripting Through Unsanitized Participant Metadata
- Content
View full analysis
{ const agent = p.profile || p.participant || ''; const avatar = getParticipantAvatar(agent); const name = escapeHtml(p.display_name || p.profile || '?'); const roleType = getRoleType(p.role || ''); const speechCount = state.speeches ? state.speeches.filter(s => s.participant === agent).length : 0; return `${avatar} ``` The streaming speech renderer contains a similar sink: ```javascript const avatar = getParticipantAvatar(agent); const speakerName = escapeHtml(meta.name); const safeRoleName = escapeHtml(meta.role); const round = roundNum > 0 ? `R${roundNum}` : ''; const roleTagClass = getRoleTagClass(meta.roleType); div.innerHTML = `${avatar}``` ### Technical Analysis Participant metadata is supplied by the caller during discussion creation and is copied into the web viewer's discussion data. The viewer obtains the participant avatar through `getParticipantAvatar()` and inserts it directly into an `innerHTML` template without HTML sanitization or contextual output encoding. The `renderMarkdown()` function uses DOMPurify when a ...[truncated 2029 chars]- Remediation
View remediation
