T09 · Insecure Skill Coding Practices
- Location
scripts/dashboard_gen.py:236- Finding
Stored Cross-Site Scripting in Generated HTML Dashboards
- Content
View full analysis
{chart["title"]}
' ``` ```python charts_js += f''' new Chart(document.getElementById('{chart["id"]}'), {json.dumps(config)});''' ``` The generated values are subsequently inserted into the final document: ```python{chart_canvases}``` ```python ``` ### Technical Analysis The generator processes attacker-controllable JSON and CSV content, including column names and categorical values. These values are used to construct chart titles, labels, and dataset labels. Chart titles are inserted directly into an HTML heading without HTML escaping: ```python{chart["title"]}
``` Consequently, a malicious column name containing HTML can introduce arbitrary elements or event handlers into the generated dashboard. Chart configuration data is passed through `json.dumps()` and embedded in an inline `` can terminate the surrounding script at the HTML parser level, even when that sequence appears inside a valid JavaScript string. The remainder of the input can then inject a new executable script element. The table and dashboard title use `html.escape()`, but the chart title and inline chart configuration paths do not receive equivalent contextual output encoding. ### Attack Path 1. An attacker creates a JSON or CSV file with a malicio ...[truncated 1453 chars]- Remediation
View remediation
' f'{escape(chart["title"])}
' f'' f'' ) ``` 2. Do not embed untrusted JSON directly into an executable inline script. Store chart configurations in non-executable JSON elements and read them through `textContent`. 3. Before embedding serialized JSON in HTML, escape characters significant to the HTML parser: ```python def safe_json_for_html(value): return ( json.dumps(value) .replace("&", "\\u0026") .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("\u2028", "\\u2028") .replace("\u2029", "\\u2029") ) ``` 4. Generate internal canvas identifiers independently rather than deriving identifiers from untrusted data. 5. Add a restrictive Content Security Policy. Prefer external or nonce-protected scripts and avoid permitting unrestricted inline JavaScript. 6. Add regression tests covering malicious column names and values, including: ```text"> ``` The tests should verify that these strings are displayed only as text and cannot terminate or introduce HTML or script elements. ]]>
