T09 · Insecure Skill Coding Practices
- Location
scripts/token-usage-button.iife.js:104- Finding
Stored DOM XSS Through Unescaped Agent Names
- Content
View full analysis
{ const pct = Math.round(((a.total || 0) / max) * 100); const bar = ``; return ` ${a.agent}${bar} ${a.calls || 0} ${fmt(a.input)} ${fmt(a.output)} ${fmt(a.cacheRead)} ${fmt(a.cacheWrite)} ${fmt(a.total)} ${fmt(a.billable)} `; }).join(""); ``` The generated markup is subsequently assigned to `innerHTML`: ```javascript const resp = await fetch(DATA_URL + "?t=" + Date.now(), { cache: "no-cache" }); if (!resp.ok) throw new Error("HTTP " + resp.status + " — " + DATA_URL); const data = await resp.json(); body.innerHTML = render(data); ``` ### Technical Analysis The `a.agent` value is not a trusted constant. The Python aggregator derives it from a directory name beneath `~/.openclaw/agents` and includes it directly in the generated JSON: ```python agent = path.split(os.sep + "agents" + os.sep)[1].split(os.sep)[0] ``` The browser payload interpolates this value into an HTML template without escaping and assigns the result to `body.innerHTML`. Consequently, markup contained in an agent directory name or in a tampered `agent-token-usage.json` file is interpreted as HTML rather than displayed as text. A malicious value can inject arbitrary elements into the token-usage modal. Depending on the Control UI Content Security Policy and browser enforcement, an event-handler or equivalent browser-compatible payload may execute JavaScript. Even where CSP blocks script execution, arbitrary HTML injection remains possible and can be used for UI spoofing, misleading link ...[truncated 2318 chars]- Remediation
View remediation
`, `"`, and `'`. A maintained sanitizer may be used only when intentional HTML support is required. 6. **Apply a restrictive Control UI CSP** that disallows inline script, inline event handlers, `javascript:` navigation, and unauthorized network destinations. CSP should be treated as defense in depth rather than the primary fix. 7. **Protect the generated data file.** Ensure it is writable only by the intended user or service and served only through the authenticated Control UI. ]]>
