T09 · Insecure Skill Coding Practices
- Location
scripts/viz.py:48- Finding
Unescaped Dataset Values Allow SVG Content Injection
- Content
View full analysis
', f'{title}', ``` ```python for i, (c, v) in enumerate(zip(cats, vals)): h = (v / mx) * (H - 2 * PAD) x = PAD + i * bw y = H - PAD - h s.append(f'') if i < 12: s.append(f'{str(c)[:6]}') ``` ```python groups = {} for r in rows: if not is_number(r.get(num, "")): continue groups.setdefault(r.get(cat, "?"), []).append(float(r[num])) if not groups: continue items = sorted(groups.items(), key=lambda kv: st.mean(kv[1]), reverse=True)[:args.topn] cats = [k for k, _ in items] vals = [st.mean(v) for _, v in items] ``` ### Technical Analysis The chart generator interpolates dataset-controlled column names and category values directly into SVG XML text elements without XML escaping. Category values originate from CSV or JSON records, are stored in `groups`, copied into `cats`, and ultimately inserted into a `` element by `bar_chart`. Because characters such as `<`, `>`, `&`, single quotes, and double quotes are not encoded, a crafted category can terminate the intended text element and introduce additional SVG elements. Column names are also propagated into chart titles and inserted into `svg_frame` without escaping, creating another injection sink. An attacker can therefore include SVG markup in an otherwise valid dataset. The generated file will contain that markup as active XML rather than harmless text. Whether scr ...[truncated 1678 chars]- Remediation
View remediation
` and other active SVG elements - Entity characters such as `&` - Quotes and angle brackets - Path separators in column names 5. Consider applying a restrictive Content Security Policy when generated visualizations are served over HTTP. This is defense in depth and must not replace correct XML escaping. 6. Document that generated SVG files should not be opened directly until all dataset-derived values are safely encoded. ]]>
