[frontend] 1162 innerHTML assignments create systemic XSS surface across JS layer #790

Open
opened 2026-06-03 00:37:44 +02:00 by sleepy · 0 comments
Owner

Finding

Across all frontend JS files, there are 1,162 innerHTML assignments vs only 51 textContent assignments in chat.js alone. Top offenders:

File innerHTML count
emailLibrary.js 82
document.js 80
documentLibrary.js 72
chat.js 67
settings.js 61
admin.js 56
sessions.js 55
chatRenderer.js 47
tasks.js 44
skills.js 36

Risk

While many of these use the esc() helper, the sheer volume makes it extremely difficult to audit which assignments properly escape user content and which do not. The issue in #788 (character name XSS) proves that escaping is inconsistent.

Recommendation

  1. Adopt a templating approach (e.g., tagged template literal that auto-escapes) to make innerHTML safer by default
  2. Prefer textContent, createElement, or a safe DOM helper for any node containing user data
  3. Add a CSP header to add defense-in-depth
  4. Audit all innerHTML assignments that interpolate variables not passed through esc()
## Finding Across all frontend JS files, there are **1,162 innerHTML assignments** vs only 51 textContent assignments in chat.js alone. Top offenders: | File | innerHTML count | |------|----------------| | emailLibrary.js | 82 | | document.js | 80 | | documentLibrary.js | 72 | | chat.js | 67 | | settings.js | 61 | | admin.js | 56 | | sessions.js | 55 | | chatRenderer.js | 47 | | tasks.js | 44 | | skills.js | 36 | ## Risk While many of these use the esc() helper, the sheer volume makes it extremely difficult to audit which assignments properly escape user content and which do not. The issue in #788 (character name XSS) proves that escaping is inconsistent. ## Recommendation 1. Adopt a templating approach (e.g., tagged template literal that auto-escapes) to make innerHTML safer by default 2. Prefer textContent, createElement, or a safe DOM helper for any node containing user data 3. Add a CSP header to add defense-in-depth 4. Audit all innerHTML assignments that interpolate variables not passed through esc()
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sleepy/odysseus#790
No description provided.