T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/risk-matrix-gen.py:240
- Finding
- Stored HTML and Script Injection in Generated Risk Reports## Vulnerability Details **File Location**: `scripts/risk-matrix-gen.py`, lines 240-258 **Vulnerability Type**: Unescaped HTML injection **Risk Level**: Medium ### Vulnerable Code ```python for r in sorted_risks: card_class = r["risk_level"] html.append(f'<div class="risk-card {card_class}">') html.append(f'<h3>{r["risk_emoji"]} {r["name"]} <small>(风险值: {r["score"]})</small></h3>') html.append(f'<div class="meta">') html.append(f'概率: {r["probability_label"]} × 影响: {r["impact_label"]} | ') if r["domain"]: html.append(f'风险域: {r["domain"]} | ') if r["source"]: html.append(f'来源: {r["source"]} | ') if r["reversibility"]: html.append(f'可逆性: {r["reversibility"]}') html.append('</div>') if r["mitigation"]: html.append(f'<p>缓解措施: {r["mitigation"]}</p>') html.append(f'<p><strong>行动建议:</strong> {r["action"]}</p>') html.append('</div>') ``` ### Technical Analysis The `generate_html_matrix()` function inserts values from risk records directly into an HTML document using formatted strings. No HTML contextual encoding or sanitization is applied. Attacker-controlled values in fields such as `name`, `domain`, `source`, `reversibility`, and `mitigation` can therefore break out of their intended text context and introduce arbitrary HTML elements or JavaScript event handlers. For example, a risk name containing the following value would be emitted as active markup: ```html <img src=x onerror="alert(document.domain)"> ``` The generated content is subsequently joined and written as an HTML file. A browser opening that report interprets the injected value as markup rather than plain text. The bundled command-line entry point currently generates reports from hard-coded sample records. Consequently, the demonstrated attack requires another caller or future integration to supply untrusted risk data to the reusable `generate_html_matrix()` function. ### Attack Path 1. An attacker controls or influen ...[truncated 1375 chars]
- Remediation
- ## Remediation Suggestions 1. Escape every dynamic value before inserting it into HTML: ```python from html import escape def html_text(value) -> str: return escape(str(value), quote=True) ``` Apply this function to all dynamic text fields, including `name`, `domain`, `source`, `reversibility`, `mitigation`, `action`, labels, and any future caller-supplied values. 2. Prefer a template engine configured with automatic HTML escaping rather than constructing documents through string concatenation. 3. Validate the risk-record schema before rendering: - Require expected data types. - Restrict probability and impact to integers from 1 through 5. - Restrict enumerated fields to known values where appropriate. - Reject unexpected keys and invalid risk-level values. 4. If rich HTML is intentionally supported, process it through a strict allowlist sanitizer that removes scripts, event-handler attributes, unsafe URL schemes, embedded objects, and other active content. 5. Add regression tests using payloads containing: - `<script>` elements. - Event handlers such as `onerror`. - Encoded angle brackets and ampersands. - Single and double quotation marks. - Closing tags intended to escape the surrounding element. 6. When reports are hosted, deploy a restrictive Content Security Policy as defense in depth. This does not replace correct output encoding.
