T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/md_to_page.py:25
- Finding
- Stored HTML and JavaScript Injection in Generated Pages<![CDATA[ ## Vulnerability Details **File Location**: `scripts/md_to_page.py`, lines 25–26, 100–121, 646–676, and 1074–1075 **Vulnerability Type**: Stored HTML injection and cross-site scripting in generated HTML **Risk Level**: High ### Vulnerable Code ```python def escape(text: str) -> str: return html_module.escape(text, quote=False) ``` ```python def inline_md(text: str) -> str: """Convert inline markdown: bold, italic, code, links, images.""" # Images text = re.sub( r'!\[([^\]]*)\]\(([^)]+)\)', lambda m: f'<img src="{escape(m.group(2))}" alt="{escape(m.group(1))}" style="max-width:100%;border-radius:8px;margin:0.5rem 0">', text, ) # Links text = re.sub( r'\[([^\]]+)\]\(([^)]+)\)', lambda m: f'<a href="{escape(m.group(2))}" target="_blank" style="color:var(--accent);text-decoration:underline">{m.group(1)}</a>', text, ) # Inline code text = re.sub( r'`([^`]+)`', lambda m: f'<code style="background:var(--bg-code);padding:0.15em 0.4em;border-radius:4px;font-size:0.9em">{escape(m.group(1))}</code>', text, ) # Bold text = re.sub(r'\*\*(.+?)\*\*', r'<strong>\1</strong>', text) # Italic (single *) text = re.sub(r'(?<!\*)\*([^*]+?)\*(?!\*)', r'<em>\1</em>', text) return text ``` Representative rendering sinks include: ```python elif btype == 'paragraph': text = inline_md(block[1]) content_html.append(f' <p class="reveal">{text}</p>') elif btype == 'blockquote': text = block[1] if text.strip().startswith('💡'): cls = 'callout insight reveal' text = text.replace('💡', '', 1).strip() elif text.strip().startswith('⚠️'): cls = 'callout warn reveal' text = text.replace('⚠️', '', 1).strip() else: cls = 'callout reveal' content_html.append(f' <div class="{cls}">{inline_md(text)}</div>') elif btype == 'ul': items_html = '\n'.join(f' <li>{inline_md(item)}</li ...[truncated 3170 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Use a maintained Markdown rendering library with explicit safe-mode or HTML-sanitization support rather than constructing HTML with regular expressions. 2. Disable raw HTML in Markdown by default. If raw HTML is required, sanitize the rendered result with a strict allowlist of elements and attributes. 3. Escape all source text before applying controlled Markdown transformations. 4. Change context-sensitive escaping to encode quotation marks: ```python html_module.escape(value, quote=True) ``` 5. Escape link labels, directive attributes, headings, and all other user-controlled text before inserting them into HTML. 6. Parse URLs and permit only required schemes: - Links: normally `http`, `https`, and optionally `mailto`. - Images: normally `http`, `https`, and explicitly generated image `data:` URIs. - Reject `javascript:`, `vbscript:`, and unexpected `data:` content. 7. Add `rel="noopener noreferrer"` to links opened with `target="_blank"`. 8. Add a restrictive Content Security Policy to generated pages. Avoid allowing inline scripts or inline event handlers where possible. 9. Add regression tests containing raw `<script>` tags, event-handler attributes, quote-breaking URLs, encoded `javascript:` URLs, malformed Markdown, and nested directive content. ]]>
