Summary
Script names and relative_path values are interpolated directly into onclick handler strings in renderSidebar() without any escaping. A maliciously-named script file breaks out of the JS string and executes arbitrary code.
Location
ui/app.js — renderSidebar(), renderWelcomeStats()
Vulnerable patterns:
onclick="selectScript('${s.relative_path}')"
onclick="toggleCategory('${cat}')"
onclick="toggleFavorite('${s.relative_path}')"
Steps to Reproduce
- Create a script file named: test'; alert(1); '.sh
- Refresh the app
- Script appears in sidebar
- Sidebar renders: onclick="selectScript('test'; alert(1); '.sh')"
- alert() executes
Risk
Stored XSS. Attacker needs write access to scripts/ directory or can social engineer via GitHub import.
Proposed Fix
Replace onclick string handlers with addEventListener via dataset attributes or pass all interpolated values through escapeAttr().
Summary
Script names and relative_path values are interpolated directly into onclick handler strings in renderSidebar() without any escaping. A maliciously-named script file breaks out of the JS string and executes arbitrary code.
Location
ui/app.js — renderSidebar(), renderWelcomeStats()
Vulnerable patterns:
onclick="selectScript('${s.relative_path}')"
onclick="toggleCategory('${cat}')"
onclick="toggleFavorite('${s.relative_path}')"
Steps to Reproduce
Risk
Stored XSS. Attacker needs write access to scripts/ directory or can social engineer via GitHub import.
Proposed Fix
Replace onclick string handlers with addEventListener via dataset attributes or pass all interpolated values through escapeAttr().