T09 · Insecure Skill Coding Practices
- Location
scripts/generate_visual.py:112- Finding
Stored HTML Attribute Injection Through Unvalidated Checklist Status
- Content
View full analysis
{_h(c.get("text", ""))} {_h(status)}\n' ``` ### Technical Analysis The `status` value is inserted directly into a double-quoted HTML `class` attribute without escaping or validation: ```html ``` Although the same value is passed through `_h()` when rendered as visible text, its use inside the `class` attribute remains unprotected. The summary JSON may be generated from attacker-influenced session content through an LLM. The prompt asks the model to use `ready`, `pending`, or `blocked`, but prompt instructions do not constitute a security boundary. For example, the following JSON value can terminate the `class` attribute and add an event handler: ```json { "text": "Open this item", "status": "ready\" onmouseover=\"alert(document.domain)" } ``` This produces markup equivalent to: ```html ``` The resulting payload executes when the generated report is opened and the event is triggered. The HTML document does not impose a Content Security Policy that would prevent inline event handlers. ### Attack Path 1. An attacker places adversarial content in a session that will be summarized, or otherwise controls the summary JSON supplied to the renderer. 2. The resulting `checklist[].status` value contains a quotation mark and an injected HTML event handler. 3. `render_html()` inserts the value into the `class` attribute without escaping or allowlist validation. 4. The Skill writes the generated content to an HTML file. 5. The user opens the file in a browser. 6. The injected event is triggered, causing at ...[truncated 679 chars]- Remediation
View remediation
` element. Avoid allowing inline event handlers. 6. Add regression tests with payloads containing quotation marks, event handlers, tags, and malformed status values. ]]>
