T09 · Insecure Skill Coding Practices
- Location
SKILL.md:231- Finding
Unescaped Values in Generated HTML Data Tables
- Content
View full analysis
{title} {"".join([f"" for c in columns])} ''' for row in data: html += '' + "".join([f"" for v in row]) + '' html += '
' return html ``` ### Technical Analysis The documented `create_data_table` implementation inserts `title`, column names, and row values directly into an HTML document. These values are converted to strings but are not HTML-escaped or sanitized. If any value originates from an untrusted dataset, an attacker can supply HTML elements or browser-executable event handlers. For example, a cell containing an image element with an error event handler would be emitted unchanged into the generated report. This issue is present in the operational instructions in `SKILL.md`. Users or agents following the documented implementation would reproduce the vulnerable behavior even though the function is not defined in the primary Python module. ### Attack Path 1. An application accepts report data, column names, or a report title from an untrusted source. 2. The application passes those values to the documented `create_data_table` function. 3. The function concatenates the attacker-controlled value into the HTML without contextual encoding. 4. The generated content is saved or embedded in an HTML report. 5. A user opens the report in a browser. 6. The injected markup is interpreted in the report's browser context, and active content may execute if browser policy permits it. ### Impact Assessment Successful exploitation can modify report content, create dec ...[truncated 368 chars]{c} {v} - Remediation
View remediation
{safe_title} {"".join(f"" for column in safe_columns)} ''' for row in data: safe_values = [escape(str(value), quote=True) for value in row] html += "" + "".join( f"" for value in safe_values ) + "" html += "
" return html ``` Additional hardening measures: - Prefer an auto-escaping template engine rather than manual string concatenation. - Treat dataset labels, titles, and cell values as untrusted by default. - Do not attempt to prevent injection using incomplete deny lists. - Apply a restrictive Content Security Policy when serving generated reports. - Add tests containing HTML metacharacters and active-content payloads to verify that output is encoded. ]]>{column} {value}
