T09 · Insecure Skill Coding Practices
- Location
parsers/generic.py:64- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
list[str]: """Return a deduplicated, order-preserved list of URLs found in *text*.""" seen: set[str] = set() urls: list[str] = [] for match in _URL_PATTERN.finditer(text): url = match.group(0).rstrip(".,;:!?)") # strip trailing punctuation if url not in seen: seen.add(url) urls.append(url) return urls ``` The generic parser then fetches that destination and follows redirects automatically: ```python def _fetch_html(self, url: str) -> str | None: """Download the raw HTML content of *url*.""" response = requests.get( url, headers=self._get_headers(), timeout=self.timeout, allow_redirects=True, ) response.raise_for_status() return response.text ``` ### Technical Analysis Any URL that is not classified as Twitter, Reddit, or YouTube is passed to `GenericParser`. The implementation does not resolve and inspect the destination address before making the request. Consequently, an attacker can supply URLs targeting: - Loopback interfaces such as `127.0.0.1` or `::1` - RFC1918 private networks - Link-local addresses - Cloud instance metadata services - Internal DNS names - Reserved or otherwise non-public address ranges Setting `allow_redirects=True` also permits a public endpoint to redirect the request to a private destination. No validation is performed after a redirect or after DNS resolution, leaving the implementation exposed to redirect-ba ...[truncated 2019 chars]- Remediation
View remediation
