T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/tech_news.py:462
- Finding
- Untrusted RSS Content Is Rendered as Markdown Without Adequate Sanitization<![CDATA[ ## Vulnerability Details **File Location**: `scripts/tech_news.py:462-513` **Vulnerability Type**: Untrusted content injection into Markdown output **Risk Level**: Medium ### Vulnerable Code ```python def display_news_list_markdown(news_list: list[NewsItem], show_summary: bool = False) -> str: """返回 Markdown 格式的新闻列表(source 带链接)""" if not news_list: return "⚠️ 没有获取到新闻" headers = ["#", "标题", "来源", "发布时间"] if show_summary: headers.append("摘要") md = [] md.append("| " + " | ".join(headers) + " |") md.append("| " + " | ".join(["---"] * len(headers)) + " |") for idx, news in enumerate(news_list, 1): # 👉 source 加链接(假设 news.link 存在) source_md = news.source if getattr(news, "link", None): source_md = f"[{news.source}]({news.link})" row = [ str(idx), news.title, source_md, news.published or "N/A", ] if show_summary: summary = ( news.summary.replace("<br/>", " ").replace("<br>", " ") if news.summary else "" ) summary = summary[:100] + "..." if len(summary) > 100 else summary row.append(summary) # 转义 Markdown 特殊字符(避免破坏表格) row = [str(cell).replace("|", "\\|") for cell in row] md.append("| " + " | ".join(row) + " |") return "\n".join(md) ``` ### Technical Analysis Article titles, links, publication dates, and summaries originate from remote RSS documents. The Markdown formatter inserts these values into the generated table while escaping only the pipe character. Summary handling removes only two specific HTML break-tag forms. The implementation does not adequately handle: - Embedded newlines capable of creating additional Markdown blocks or table rows. - Markdown link syntax and other formatting metacharacters. - Raw HTML accepted by some Markdown renderers. - Terminal or Unicode control cha ...[truncated 2060 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat every RSS field as untrusted input, including the title, summary, date, and link. 2. Remove HTML with a dedicated allowlist-based sanitizer rather than replacing only `<br>` variants. 3. Remove terminal escape sequences, control characters, and bidirectional text-control characters. 4. Collapse carriage returns and newlines before inserting values into a Markdown table. 5. Escape all Markdown metacharacters relevant to the output context, not only pipe characters. 6. Parse every article URL before rendering it: - Allow only `https`. - Reject credentials, malformed hostnames, and non-web schemes. - Consider restricting links to the feed provider's expected domains or clearly label external domains. 7. Keep remote article text inside a clearly delimited data section and instruct the consuming agent never to interpret feed content as commands. 8. Consider emitting structured JSON and allowing a trusted presentation layer to perform context-specific encoding. 9. Add tests containing malicious titles, summaries, and links, including embedded newlines, raw HTML, Markdown links, control characters, and non-HTTPS schemes. ]]>
