T09 · Insecure Skill Coding Practices
- Location
scripts/generate_chart.py:302- Finding
Stored HTML Injection Through Untrusted Dataset Values
- Content
View full analysis
= 0 else "#ef4444" change_icon = "↑" if change >= 0 else "↓" change_html = f'{change_icon} {abs(change):.1f}% vs 上期' return f"""""" ``` The untrusted value is obtained and passed into the HTML generator without escaping: ```python if characteristics['categorical_count'] > 0 and characteristics['numeric_count'] > 0: max_cat = df[categorical_cols[0]].value_counts().idxmax() metrics_html += create_metric_card(f"最常见{categorical_cols[0]}", f"{max_cat}", icon="🏷️", color="#10B981") ``` The resulting markup is inserted directly into the output document: ```html{icon}{title}{value}{change_html}{metrics_html}``` ### Technical Analysis The input CSV or Excel file is treated as untrusted data. Both column names and categorical valu ...[truncated 2193 chars]- Remediation
View remediation
{safe_title}{safe_value}``` 3. Escape all column names, categorical values, labels, and other user-controlled strings that enter the surrounding HTML template. 4. Prefer a template engine with automatic escaping enabled rather than constructing HTML with unrestricted f-strings. 5. If selected HTML formatting must be supported, pass values through a well-maintained allowlist-based HTML sanitizer. Do not rely on removing only `script` elements, because event handlers, unsafe URLs, and other active content can also execute. 6. Add regression tests using values containing: - HTML elements. - Closing tags. - Event-handler attributes. - Single and double quotes. - Encoded and mixed-case payload variants. 7. Consider applying a restrictive Content Security Policy to generated dashboards as defense in depth, while retaining output encoding as the primary control. ]]>
