T09 · Insecure Skill Coding Practices
- Location
scripts/risk-matrix-gen.py:240- Finding
Stored HTML and Script Injection in Generated Risk Reports
- Content
View full analysis
Vulnerability Details
File Location:
scripts/risk-matrix-gen.py, lines 240-258
Vulnerability Type: Unescaped HTML injection
Risk Level: MediumVulnerable 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, andmitigationcan 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
- An attacker controls or influen ...[truncated 1375 chars]
- Remediation
View remediation
Remediation Suggestions
- 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.-
Prefer a template engine configured with automatic HTML escaping rather than constructing documents through string concatenation.
-
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.
-
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.
-
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.
-
When reports are hosted, deploy a restrictive Content Security Policy as defense in depth. This does not replace correct output encoding.
