T09 · Insecure Skill Coding Practices
- Location
- references/schema.py:526
- Finding
- Stored JavaScript Injection in Generated Wiki Reports<![CDATA[ ## Vulnerability Details **File Location**: `references/schema.py:526-687` **Vulnerability Type**: Stored HTML/JavaScript injection **Risk Level**: High ### Vulnerable Code ```javascript cardsEl.innerHTML = cc.map(c => `<div class="card"><div class="num">${c.num}</div><div class="label">${c.label}</div></div>`).join(''); ``` ```javascript ndBody.innerHTML = html; ``` ```javascript dtEl.innerHTML = `<table><thead><tr><th>Page</th><th>Field</th><th class="r">Value</th><th>Unit</th><th>Period</th><th>Conf.</th></tr></thead><tbody>` + DATA.data_rows.map(r => `<tr><td>${r.page}</td><td>${r.field}</td><td class="r"><b>${r.value}</b></td><td>${r.unit}</td><td>${r.period}</td><td><span class="badge badge-${r.confidence}">${r.confidence}</span></td></tr>` ).join('') + '</tbody></table>'; ``` ```python def generate_report(wiki_dir: Path) -> Path: """生成 wiki 可视化报告 HTML。返回输出文件路径。""" data = collect_report_data(wiki_dir) html = REPORT_HTML_TEMPLATE html = html.replace("{{WIKI_NAME}}", data["name"]) html = html.replace("{{WIKI_DESC}}", data.get("description", "")) html = html.replace("{{ONTOLOGY_TYPE}}", data.get("ontology_type", "")) html = html.replace("{{TOTAL_PAGES}}", str(data["total_pages"])) html = html.replace("{{JSON_DATA}}", json.dumps(data, ensure_ascii=False, default=str)) out_path = wiki_dir / "_report.html" out_path.write_text(html, encoding="utf-8") return out_path ``` ### Technical Analysis The report generator incorporates wiki-controlled metadata and page-derived values directly into an HTML document. Some values are inserted through string replacement, while the complete data model is embedded in an inline script using `json.dumps()`. JSON serialization alone is not sufficient for safe embedding inside an HTML `<script>` element. In particular, an attacker-controlled value containing `</script>` can terminate the original script element and inject new HTML or JavaScript. The generated c ...[truncated 1883 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not insert untrusted values into HTML using raw string replacement. 2. Construct report elements with DOM APIs and assign untrusted values using `textContent`, not `innerHTML`. 3. If limited markup is required, process it through a well-maintained HTML sanitizer with a restrictive allowlist. 4. Escape HTML placeholders using an appropriate HTML-escaping function. 5. Before embedding JSON in a script element, escape at least: - `<` as `\u003c` - `>` as `\u003e` - `&` as `\u0026` - U+2028 and U+2029 as Unicode escapes 6. Prefer placing serialized data in an inert `<script type="application/json">` element and parse its `textContent`. 7. Validate slugs, relation types, confidence values, and other identifier-like fields against strict allowlists. 8. Add a restrictive Content Security Policy. If inline scripts remain necessary, use a nonce or hash rather than allowing unrestricted inline execution. 9. Add regression tests using payloads containing: ```text </script><script>alert(1)</script> <img src=x onerror=alert(1)> ${maliciousValue} ``` ]]>
