T09 · Insecure Skill Coding Practices
- Location
grazer/podcast_grazer.py:122- Finding
Unrestricted Podcast Feed URL Enables Server-Side Request Forgery
- Content
View full analysis
List[Dict]: """Fetch recent episodes from a podcast RSS feed. Args: feed_url: The podcast's RSS feed URL limit: Maximum episodes to return Returns: List of episode dicts with title, description, audio_url, etc. """ resp = self.session.get(feed_url, timeout=self.timeout) resp.raise_for_status() eps = _parse_podcast_rss(resp.text) return eps[:limit] ``` The method is exposed through the main client: ```python def podcast_episodes(self, feed_url: str, limit: int = 10) -> List[Dict]: """Fetch recent episodes from a podcast RSS feed URL.""" return self._podcast.episodes(feed_url, limit=limit) ``` ### Technical Analysis `feed_url` is passed directly to `requests.Session.get()` without validating its scheme, destination hostname, resolved IP address, port, or redirect chain. The request library follows HTTP redirects by default. Consequently, an untrusted caller can direct the process to arbitrary HTTP services reachable from its execution environment. This includes loopback services, private network hosts, link-local addresses, container-management endpoints, and cloud instance metadata services. A timeout does not prevent SSRF. There is also no response-size limit, so a hostile endpoint may return an excessively large body before the code accesses `resp.text`. ### Attack Path 1. An attacker gains control over the `feed_url` argument, directly or through an agent workflow that treats externally supplied podcast URLs as trusted. 2. The attacker supplies a URL such as: - `http://127.0.0.1:8080/internal` - `http://169.254.169.254/latest/meta-data/` - A public HTTPS URL that redirects to a ...[truncated 912 chars]- Remediation
View remediation
