T09 · Insecure Skill Coding Practices
Error
- Location
- generate_mindmap.py:1271
- Finding
- Untrusted Mind-Map Content Can Inject JavaScript into Generated HTML<![CDATA[ ## Vulnerability Details **File Location**: `generate_mindmap.py:1053`, `generate_mindmap.py:1215`, `generate_mindmap.py:1271-1275`, `generate_mindmap.py:3211-3218`, `generate_mindmap.py:3645-3646`, `generate_mindmap.py:3693-3694` **Vulnerability Type**: HTML and JavaScript injection through unsafe template substitution **Risk Level**: High ### Vulnerable Code The title is inserted directly into HTML text contexts: ```python <title>__TITLE__</title> ``` ```html <h1>🧠 __TITLE__</h1> ``` Untrusted title and tree data are also inserted into an executable script element: ```html <script> /*__MINDMAP_DATA_START__*/ const RAW = __RAW_JSON__; const TITLE = __TITLE_JSON__; const INIT_THEME = "__THEME__"; /*__MINDMAP_DATA_END__*/ ``` The template substitutions do not perform HTML-parser-safe escaping: ```python def render_html(title, js_data, theme="midnight"): if theme not in THEMES: theme = "midnight" return (_HTML .replace("__TITLE__", title) .replace("__RAW_JSON__", js_data) .replace("__TITLE_JSON__", json.dumps(title, ensure_ascii=False)) .replace("__THEME__", theme) .replace("__DATE__", datetime.now().strftime("%Y-%m-%d %H:%M"))) ``` Both HTML generation and Playwright image rendering use this output: ```python if fmt in ("png", "jpg") and _has_playwright(): html_str = render_html(title, json.dumps(tree, ensure_ascii=False), theme=args.theme) _export_image_playwright(html_str, out, fmt, scale=args.scale, quality=args.quality) ``` ```python html = render_html(title, json.dumps(tree, ensure_ascii=False), theme=args.theme) open(out, "w", encoding="utf-8").write(html) ``` ### Technical Analysis The Skill accepts titles and node labels from command-line arguments, Markdown files, JSON files, or standard input. These values are therefore potentially untrusted. Al ...[truncated 3299 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not place raw JSON directly into an executable script context. 2. Store initial data in a non-executable element and safely parse it, for example: ```html <script id="mindmap-data" type="application/json">SAFE_JSON</script> ``` ```javascript const RAW = JSON.parse(document.getElementById("mindmap-data").textContent); ``` 3. Even in an `application/json` element, escape characters significant to the HTML parser. At minimum, encode: - `<` as `\u003c` - `>` as `\u003e` - `&` as `\u0026` - U+2028 as `\u2028` - U+2029 as `\u2029` 4. Apply context-specific HTML escaping to title substitutions used in `<title>` and `<h1>`, such as `html.escape(title, quote=True)`. 5. Avoid applying one placeholder replacement to both HTML and JavaScript contexts. Use separate, context-aware placeholders. 6. Add regression tests containing: - `</script>` - `<img src=x onerror=...>` - Quotes and backslashes - U+2028 and U+2029 - Nested malicious labels in both Markdown and JSON 7. Add a restrictive Content Security Policy. Refactor inline scripts and inline event handlers so that `script-src` does not require `unsafe-inline`. 8. Do not launch Chromium with `--no-sandbox` unless execution occurs inside a separately enforced operating-system sandbox or container. 9. If untrusted input must be rendered through Playwright, disable unnecessary browser capabilities and block outbound network requests during rendering. ]]>
