T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/generate-ai-news.py:166
- Finding
- Untrusted RSS Content Is Embedded in Markdown Without Escaping or URL Validation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-ai-news.py`, lines 166-181 **Vulnerability Type**: Markdown injection and unsafe remote-resource embedding **Risk Level**: Medium ### Vulnerable Code ```python # Headlines for article in top_articles[:3]: content += f"""### {article['title']} 📍 **{article['source']}** | 🕐 {article['pubDate']} 💡 {article['summary']} 🔗 [Read full article]({article['link']}) """ if article['images']: for img in article['images']: content += f"\n" content += "\n" ``` The translated labels above correspond to the original user-facing labels; the interpolation and executable behavior are unchanged. ### Technical Analysis The values in `article['title']`, `article['summary']`, `article['link']`, and `article['images']` originate from externally retrieved RSS or Atom documents. They are interpolated directly into the generated Markdown document. The summary function removes HTML-like tags with a regular expression, but it does not escape Markdown metacharacters. Titles and URLs receive no sanitization at all. The implementation also does not restrict URL schemes, validate hostnames, or prevent control characters and crafted delimiters from changing the Markdown structure. Consequently, a malicious or compromised feed can inject: - Additional Markdown headings, links, images, or quoted instructions. - Deceptive links whose displayed text does not represent their destination. - Attacker-controlled remote images used for tracking. - Unsafe URI schemes if the selected Markdown renderer permits them. - Prompt-like content that could influence an AI agent consuming the generated digest without treating it as untrusted data. Actual script execution depends on the security behavior of the Markdown renderer. The generator itself does not execute content received from the feed. ### Attack Path 1. An attacker gains control of a configured RSS source, compromi ...[truncated 1534 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Escape Markdown metacharacters in all untrusted textual fields, including titles, summaries, source names, and publication dates. 2. Parse links and image URLs with `urllib.parse.urlsplit()` and permit only explicitly approved schemes, preferably `https`. 3. Reject URLs containing control characters, invalid delimiters, embedded credentials, or malformed hostnames. 4. Consider restricting links and images to the hostname of the configured feed or to a maintained allowlist. 5. Disable external images by default. If images are required, download and validate them through a trusted proxy that enforces content type, size, redirect, and destination restrictions. 6. Do not pass the digest to an AI agent as trusted instructions. Clearly delimit feed content as untrusted data and instruct downstream agents not to follow instructions contained within articles. 7. Use a Markdown-aware escaping library rather than regular expressions intended only to remove HTML tags. 8. Add tests containing crafted titles, descriptions, and URLs to confirm that injected Markdown cannot alter document structure. ]]>
