T09 · Insecure Skill Coding Practices
- Location
scripts/md2ppt.py:68- Finding
Unescaped Markdown Content Enables HTML Injection in Fallback Output
- Content
View full analysis
Vulnerability Details
File Location:
scripts/md2ppt.py, lines 68–74
Vulnerability Type: HTML injection and potential script execution
Risk Level: MediumVulnerable 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, andcodevalues 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-pptxmodule 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
- An attacker prepares a Markdown document containing malicious HTML in a heading, bullet, or fenced code block.
- The attacker persuades a victim to convert that document using this Skill.
- The victim's environment does not have
python-pptxinstalled, causing the converter to select its HTML fallback. - The malicious value is inserted verbatim into the generated HTML file.
- The victim opens the generated presentation in a browser.
- 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
View 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-pptxis unavailable so the fallback path receives routine security coverage.
