T09 · Insecure Skill Coding Practices
- Location
scripts/md_to_html.py:6- Finding
Unescaped Markdown Enables Script Injection in Generated HTML
- Content
View full analysis
\1", html, flags=re.MULTILINE) html = re.sub(r"^## (.+)$", r"\1
", html, flags=re.MULTILINE) html = re.sub(r"^# (.+)$", r"\1
", html, flags=re.MULTILINE) # Bold/italic html = re.sub(r"\*\*(.+?)\*\*", r"\1", html) html = re.sub(r"\*(.+?)\*", r"\1", html) # Code html = re.sub(r"`(.+?)`", r"\1", html) # Links html = re.sub(r"\[(.+?)\]\((.+?)\)", r'\1', html) # Paragraphs paragraphs = [p.strip() for p in html.split(" ") if p.strip()] html = "\n".join(f"{p}
" if not p.startswith("<") else p for p in paragraphs) return f""" Converted {html}""" ``` ### Technical Analysis The converter initially assigns the complete, untrusted Markdown input to `html` and then performs regular-expression substitutions without first HTML-encoding input text. Any HTML elements already present in the Markdown therefore remain active in the generated document. The paragraph construction further preserves content beginning with `<` instead of wrapping or sanitizing it: ```python html = "\n".join(f"{p}
" if not p.startswith("<") else p for p in paragraphs) ``` Consequently, payloads such as the following can become executable browser content: ```html ``` ```html``` The link conversion also inserts the attacker-controlled destination directly into an `href` attribute without attribute escaping or URL-scheme validation: ```python html = re.sub(r"\[(.+?)\]\((.+?)\)", r'
- Remediation
View remediation
` elements. - Test event attributes such as `onerror`. - Test attribute-breaking quotation marks. - Test `javascript:` and dangerous `data:` URLs. - Verify that ordinary Markdown still produces correctly encoded HTML. ]]>
