T09 · Insecure Skill Coding Practices
- Location
scripts/render_architecture.py:1446- Finding
Stored Script Injection Through Unescaped SVG Attributes
- Content
View full analysis
' return f''' ``` The same unsafe attribute-encoding pattern is used for node identifiers: ```python shape_group = f'\n' + "\n".join(shape_parts) + "\n" ``` It also affects share-card SVG titles: ```python title = escape(data.get("title", "visual-architecture")) ... return f''' ``` ### Technical Analysis `xml.sax.saxutils.escape()` escapes XML text characters such as `&`, `<`, and `>`, but it does not escape quotation marks unless an additional entity mapping is explicitly supplied. The escaped value is inserted into a double-quoted XML attribute. An attacker-controlled title containing a double quote can therefore terminate the `aria-label` value and introduce additional SVG attributes. For example: ```json { "title": "x\" onload=\"alert(document.domain)" } ...[truncated 1866 chars]- Remediation
View remediation
' ``` Apply the same treatment to every value placed in an XML or HTML attribute: ```python node_id_attr = quoteattr(str(node.get("id", ""))) shape_group = f'...' ``` Additional hardening should include: 1. Audit all generated HTML and SVG attributes and distinguish text-content encoding from attribute encoding. 2. Continue using `escape()` for XML text nodes, but use `quoteattr()` for XML attributes. 3. Add regression tests using double quotes, single quotes, ampersands, angle brackets, and event-handler payloads. 4. Test both standalone SVG output and SVG embedded by `render_html()`. 5. Consider a restrictive Content Security Policy for generated HTML as defense in depth, while recognizing that CSP does not replace correct output encoding. ]]>
