T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/md2ppt.py:68
- Finding
- Unescaped Markdown Content Enables HTML Injection in Fallback Output## Vulnerability Details **File Location**: `scripts/md2ppt.py`, lines 68–74 **Vulnerability Type**: HTML injection and potential script execution **Risk Level**: Medium ### Vulnerable Code ```python html += f'<div class="slide"><h1>{title}</h1>\n' for b in bullets: html += f'<li>{b}</li>\n' if code: html += f'<pre><code>{code}</code></pre>\n' html += '</div>\n' ``` ### Technical Analysis The HTML fallback directly interpolates Markdown-derived `title`, `bullets`, and `code` values into an HTML document without context-appropriate escaping or sanitization. Consequently, HTML metacharacters and active elements supplied through the input Markdown retain their browser semantics. The vulnerable path is reached when the optional `python-pptx` module is unavailable. In that environment, `create_pptx()` generates an HTML presentation instead of a PPTX file. A malicious input value such as an image element with an event handler can therefore become executable browser content rather than presentation text. The issue is classified as an insecure coding practice because untrusted document content crosses into an active HTML context without output encoding. ### Attack Path 1. An attacker prepares a Markdown document containing malicious HTML in a heading, bullet, or fenced code block. 2. The attacker persuades a victim to convert that document using this Skill. 3. The victim's environment does not have `python-pptx` installed, causing the converter to select its HTML fallback. 4. The malicious value is inserted verbatim into the generated HTML file. 5. The victim opens the generated presentation in a browser. 6. The browser interprets the injected markup and may execute event handlers or scripts permitted by its security policy. ### Impact Assessment Exploitation can execute attacker-controlled browser-side content in the context of the generated local presentation. This can alter or spoof presentation cont ...[truncated 466 chars]
- Remediation
- ## Remediation Suggestions Escape every untrusted value before inserting it into HTML: ```python import html safe_title = html.escape(title, quote=True) html_output += f'<div class="slide"><h1>{safe_title}</h1>\n' for bullet in bullets: safe_bullet = html.escape(bullet, quote=True) html_output += f'<li>{safe_bullet}</li>\n' if code: safe_code = html.escape(code, quote=True) html_output += f'<pre><code>{safe_code}</code></pre>\n' ``` Apply the following additional controls: - Prefer a template engine configured with automatic HTML escaping. - Treat headings, bullets, and code blocks as plain text unless raw HTML is an explicitly supported and sanitized feature. - If limited HTML formatting must be supported, sanitize it with a maintained allowlist-based HTML sanitizer rather than relying on string replacement. - Add a restrictive Content Security Policy to the generated document as defense in depth, while retaining output encoding as the primary fix. - Add regression tests for injection through headings, list items, and fenced code blocks, including event handlers, malformed tags, quotes, ampersands, and closing-tag payloads. - Ensure tests cover the environment where `python-pptx` is unavailable so the fallback path receives routine security coverage.
