T09 · Insecure Skill Coding Practices
- Location
scripts/rss_engine.py:82- Finding
Unrestricted Server-Side Feed Retrieval Enables SSRF
- Content
View full analysis
Vulnerability Details
File Location:
scripts/rss_engine.py:41-43andscripts/rss_engine.py:82-86
Vulnerability Type: Server-Side Request Forgery (SSRF) and missing network resource controls
Risk Level: HighVulnerable Code
python def add_feed(self, url: str, name: str) -> None: """添加 RSS 订阅源""" self.feeds[name] = urlpython def fetch_feed(self, name: str, url: str, limit: int = 10) -> List[Dict[str, Any]]: """抓取单个 RSS 源的文章""" articles = [] try: feed = feedparser.parse(url, request_headers={"User-Agent": "RSSAggregator/1.0"})Technical Analysis
Caller-controlled feed locations are stored without validation and passed directly to the network-capable
feedparser.parse()function. The implementation does not restrict URL schemes, destinations, ports, DNS results, or redirects.An attacker who can configure a feed can therefore cause the runtime host to request loopback, private-network, link-local, or cloud metadata addresses. This constitutes an SSRF primitive when the aggregator is exposed through an application or Agent that accepts untrusted feed URLs.
Although the constructor accepts a
timeoutvalue, that value is not used byfetch_feed(). The implementation also lacks response-size limits. A slow or unusually large endpoint could consequently consume worker time, memory, or network resources.Attack Path
- An attacker supplies a feed URL targeting an internal service, a cloud metadata endpoint, or a hostname resolving to a private address.
add_feed()stores the URL without validating its scheme, hostname, port, or resolved IP address.- The application invokes
fetch_all()or directly invokesfetch_feed(). feedparser.parse()initiates the request from the victim environment and its trusted network position.- If the response is parseable as RSS or Atom, internal response data may be exposed through article f ...[truncated 861 chars]
- Remediation
View remediation
Remediation Suggestions
- Permit only explicitly supported URL schemes, preferably
https, withhttpenabled only when necessary. - Reject URLs containing embedded credentials, malformed hosts, unsupported ports, or non-network schemes.
- Resolve hostnames before connecting and reject loopback, private, link-local, multicast, reserved, and unspecified IP address ranges for both IPv4 and IPv6.
- Repeat destination validation after every redirect and protect against DNS rebinding by ensuring the validated address is the address actually contacted.
- Explicitly block cloud metadata destinations, including link-local metadata addresses.
- Use a controlled HTTP client with separate connection and read timeouts, then pass the bounded response body to
feedparser.parse(). - Disable redirects or impose a small redirect limit.
- Enforce maximum response and decompressed-body sizes.
- Consider an allowlist of trusted feed domains where the deployment permits it.
- Add tests covering private and loopback addresses, IPv6 literals, redirects to internal destinations, DNS rebinding protections, slow responses, and oversized responses.
- Permit only explicitly supported URL schemes, preferably
