T09 · Insecure Skill Coding Practices
- Location
scripts/generate_visual.py:382- Finding
Stored HTML Attribute Injection Through Unvalidated Checklist Status
- Content
View full analysis
{_h(c.get('text', ''))} {_h(status)}\n" ``` ### Technical Analysis The checklist text and visible status value are passed through `_h()`, but the status value inserted into the `class` attribute is not escaped or validated: ```python class=\"status {status}\" ``` Although the intended status values are `ready`, `pending`, and `blocked`, the renderer does not enforce that allowlist. A crafted value containing a quotation mark can terminate the `class` attribute and inject another HTML attribute. For example, a malicious status value conceptually equivalent to: ```text ready" onmouseenter="alert(document.domain) ``` would produce an element with an attacker-controlled event handler. Session transcript content influences model-generated summary JSON, so hostile content in a summarized session could attempt to manipulate `checklist[].status`. The generated HTML is subsequently opened by Playwright during PNG generation and may later be opened interactively by the user. HTML text escaping alone is insufficient when untrusted content is interpolated into an attribute without attribute-safe encoding and semantic validation. ### Attack Path 1. An attacker places prompt-injection content in a session that the user later chooses to summarize. 2. The content instructs or induces the local summarization model to return a malicious string in `checklist[].status`. 3. `json.loads()` accepts the value because no schema or status allowlist is applied. 4. `render_html()` inserts the raw value into the `class` attribute. 5. The application writes the resulting persistent payload to the generated HTML file. 6. The ...[truncated 747 chars]- Remediation
View remediation
{_h(c.get("text", ""))} ' f'{safe_status}\n' ) ``` 3. Prefer structured HTML generation through a template engine with automatic context-aware escaping rather than manual string concatenation. 4. Validate the complete summary JSON against a schema before rendering. The schema should restrict status to an enumeration and impose types, lengths, and item-count limits. 5. Add regression tests using quotation marks, event-handler fragments, angle brackets, and malformed status values. Verify that none can create additional attributes or elements. ]]>
