T09 · Insecure Skill Coding Practices
- Location
scripts/extract_session.py:154- Finding
Stored Script Injection in Generated Session Viewer
- Content
View full analysis
', '<\\/script>') ``` The serialized session data is then embedded directly into an executable script: ```python `. HTML end-tag matching is ASCII case-insensitive, however. Consequently, variants such as `` are not modified by the Python replacement but are still interpreted by the browser as the end of the surrounding script element. An attacker-controlled value in a session log can therefore terminate the data script and introduce executable HTML or JavaScript. In addition, model names, tool names, and tool-call identifiers are concatenated directly into HTML strings assigned to `innerHTML`. A malicious value containing HTML with an event handler, such as an image element with an `onerror` attribute, could execute when the affected turn is rendered. Although ordinary message bodies and tool arguments are general ...[truncated 1767 chars]- Remediation
View remediation
``` Populate that element using an HTML-safe serializer and parse its `textContent` with `JSON.parse()`. 3. Escape all characters that can affect HTML parsing, including at minimum `<`, `>`, and `&`. Do not rely on replacing only one lowercase closing tag. 4. Prefer constructing viewer elements with `document.createElement()` and assigning untrusted values through `textContent`. 5. If HTML-string construction remains necessary, call the escaping routine for every dynamic value, including: - `r.model` - `tc.name` - `tc.id` - `tr.tool_name` 6. Apply a restrictive Content Security Policy that disallows inline scripts and event handlers. Move viewer JavaScript to a separate static file if necessary. 7. Add regression tests containing mixed-case closing script tags, event-handler markup, quotes, angle brackets, and Unicode edge cases in every extracted field. ]]>
