T09 · Insecure Skill Coding Practices
- Location
scripts/render_dashboard.py:550- Finding
Stored HTML Injection in Generated Dashboards
- Content
View full analysis
str: """渲染 VOC 分析""" if not voc_analysis or not voc_analysis.get('dimensions'): return '' dimensions = voc_analysis.get('dimensions', []) summary = voc_analysis.get('summary', '') rows = '' for dim in dimensions: dimension = dim.get('dimension', '') pain_point = dim.get('pain_point', '') frequency = dim.get('frequency', 0) percentage = dim.get('percentage', '') affected_brands = ', '.join(dim.get('affected_brands', [])) brand_opportunity = dim.get('brand_opportunity', '') product_solution = dim.get('product_solution', '') rows += f''' {dimension} {pain_point} {frequency}
{percentage} {affected_brands} {brand_opportunity} {product_solution} ''' summary_html = f'总结:{summary}' if summary else '' ``` The same unsafe interpolation pattern is also used for category metadata, product dimensions, cross-analysis data, competitors, barriers, and decision information at `scripts/render_dashboard.py:365-443`, `453-516`, `603-676`, and `782-795`. ### Technical Analysis The renderer inserts values from `data.json` directly into HTML fragments without HTML-context escaping. These values may originate from: - User-supplied product keywords. - Sorftime API responses. - Marketplace product and review content. - LLM-generated analysis. - A locally ...[truncated 1936 chars]- Remediation
View remediation
str: return escape(str(value), quote=True) ``` Apply this function to category names, site values, dates, verdict text, dimensions, review content, brand names, positioning, barrier descriptions, and all other text originating outside the template. 2. Validate numeric fields separately and convert them to expected numeric types before formatting. Do not pass arbitrary strings through numeric display fields. 3. Replace manual string interpolation with a template engine configured for automatic HTML escaping, such as Jinja2 with autoescaping enabled. 4. If rich HTML is intentionally supported, sanitize it with a strict allowlist sanitizer rather than disabling escaping. 5. Add a restrictive Content Security Policy to the generated dashboard. For example, avoid inline scripts and event handlers and restrict network destinations through `default-src`, `script-src`, and `connect-src`. 6. Add regression tests using payloads such as: ```html"> ``` Verify that the generated HTML contains escaped text rather than executable markup. ]]>
