T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/format_report.py:81
- Finding
- Unsanitized Remote Release Notes Embedded in Markdown Reports<![CDATA[ ## Vulnerability Details **File Location**: `scripts/format_report.py`, lines 81–99 and 145–153 **Vulnerability Type**: Untrusted Markdown content injection **Risk Level**: Medium ### Vulnerable Code ```python if status == "found": releases = changelog.get("releases", []) if not releases: return "_No release notes found._" lines = [] for r in releases[:3]: tag = r.get("tag", "?") name = r.get("name", tag) body = r.get("body", "").strip() # Extract first meaningful paragraph if body: # Remove markdown headers, HTML tags body = re.sub(r'<[^>]+>', '', body) # Get first non-empty lines up to 400 chars paras = [p.strip() for p in body.split("\n") if p.strip()] snippet = " ".join(paras)[:400] if len(" ".join(paras)) > 400: snippet += "…" ``` ```python if source_url or gh_repo: url = source_url or f"https://github.com/{gh_repo}" lines.append(f"- **Source:** <{url}>") lines.append("") lines.append("**Changelog:**") lines.append(changelog_summary) return "\n".join(lines) ``` ### Technical Analysis Release-note bodies retrieved from GitHub are controlled by the referenced repository and must therefore be treated as untrusted remote input. The formatter removes HTML tags, but it does not escape or remove Markdown constructs such as: - Remote images: `` - Deceptive hyperlinks: `[Security update](https://attacker.example/phish)` - Headings, block quotes, and other formatting capable of visually altering the report - Control characters or crafted text intended to obscure the report's trusted risk labels The resulting content is inserted directly into the generated Markdown report. HTML removal alone is insufficient because Markdown renderers can turn the remaining syntax into active external resources and misleading interactive content. This issue does not p ...[truncated 1804 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat all GitHub release metadata—including body, title, and tag—as untrusted input. 2. Convert release notes to escaped plain text before placing them in Markdown. At minimum, escape Markdown metacharacters such as backslashes, backticks, asterisks, underscores, braces, brackets, parentheses, angle brackets, hash signs, plus signs, minus signs, periods, exclamation marks, and pipes. 3. Explicitly remove Markdown image and link syntax rather than relying only on HTML-tag removal. 4. Strip control characters and normalize line breaks before truncation. 5. Place remote text in a clearly labeled, fenced plain-text block if compatible with the reporting format. Escape embedded backtick sequences before doing so. 6. Consider omitting release bodies entirely and reporting only validated version identifiers plus a canonical `https://github.com/<owner>/<repo>/releases` URL. 7. Add tests containing malicious examples such as remote images, phishing links, headings, tables, nested formatting, and control characters. 8. Document that changelog text originates from an external repository and is not trusted by the Skill. ]]>
