T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/mindmap_tools.py:219
- Finding
- Unescaped JSON Content Allows Stored HTML and SVG Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mindmap_tools.py:219, 223-238, 248-251, 260, 295-302` **Vulnerability Type**: Stored HTML/SVG injection **Risk Level**: High ### Vulnerable Code ```python def render_valence_svg(axis): ... for note in axis.get('special', []): svg.append(f'<text x="{note.get("x", w//2)}" y="{note.get("y", 112)}" font-size="11" text-anchor="middle" fill="#b91c1c">★{note.get("text","")}</text>') svg.append('</svg>') return '\n'.join(svg) def render_node(nd): parts = ['<div class="node">'] if nd.get('text'): parts.append(f'<span class="node-text">{nd["text"]}</span>') if nd.get('eq'): parts.append(f'<div class="eq">{nd["eq"]}</div>') extra = nd.get('extra') if extra: parts.append(f'<div class="extra">{extra}</div>') if nd.get('tag'): for t in nd['tag'].split('|'): cls = {'常考': 'tag-red', '易错': 'tag-yellow', '可推': 'tag-green', '必须记': 'tag-gray'}.get(t.strip(), 'tag-gray') parts.append(f'<span class="tag {cls}">{t.strip()}</span>') parts.append('</div>') return '\n'.join(parts) ``` Additional unescaped insertion points in `render_html` include: ```python secs.append(f'<div class="section"><div class="sec-title">▸ {sec.get("title","")}</div>{nodes}</div>') branch_html.append( f'<div class="branch-card" style="border-left-color:{color}">' f'<div class="branch-head" style="color:{color}"><span class="branch-num" style="background:{color}">{b.get("id", idx+1)}</span>{b.get("title","")}</div>' + ''.join(secs) + '</div>') <title>{meta.get('module','')}|三层思维导图</title> <h1>{meta.get('module','')}|三层思维导图</h1> <div class="sub">主题式包装:{meta.get('theme','')} | {meta.get('grade_region','')} · {meta.get('textbook','')} | 配套教案:mifu-chemistry-lesson-prep</div> <div class="footer">{stats_line} | validate: {data.get('_validate_status','未运行')} | 生成日期:{today} | 米赋教育教研中心 · mifu-chem-mindmap v{meta.get('skill_ver ...[truncated 2413 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Escape every untrusted value before inserting it into HTML text: ```python from html import escape def html_text(value): return escape(str(value), quote=True) ``` 2. Apply escaping consistently to: - Node text, equations, extra content, and tags - Section and branch titles - Module, theme, region, textbook, and version metadata - SVG note and species text - Footer values 3. Do not rely on text escaping for numeric SVG attributes. Validate and normalize them: ```python def safe_number(value, default): if isinstance(value, (int, float)): return value return default ``` 4. Validate the complete input against a strict schema before rendering. Reject unknown types, unexpected nested values, and fields exceeding reasonable size limits. 5. Prefer a template engine with autoescaping enabled rather than constructing markup through f-strings. 6. Add a restrictive Content Security Policy to generated files, such as one that disallows scripts, plugins, framing, and remote resources. CSP should be defense in depth rather than a substitute for escaping. 7. Add regression tests covering payloads in every rendered field, including: - `<script>` elements - Event-handler attributes - SVG element termination - Quotes in SVG coordinates and IDs - Remote image or frame elements ]]>
