Server-Side Request Forgery (SSRF) in mcp-rss-search via Unvalidated URL Fetching
Summary
The mcp-rss-search module, an MCP server distributed as part of IBM/mcp-context-forge, contains a Server-Side Request Forgery (SSRF) vulnerability. The fetch_feed() method in RSSParser directly fetches attacker-controlled URLs via httpx without any SSRF protections — no private IP blocking, no DNS rebinding mitigation, no URL allowlisting, and no IP address validation. An attacker who can invoke the fetch_feed MCP tool can force the server to make HTTP requests to arbitrary internal network destinations, including cloud metadata services, internal APIs, and other private network resources.
Details
Root Cause
The vulnerability exists because the fetch_feed() method in the RSSParser class (lines 52-96) performs no validation on the target URL before making an outbound HTTP request.
Trust Boundary Failure
The MCP protocol serves as a trust boundary between the caller and the server. The fetch_feed() method receives a url parameter from across this trust boundary and passes it directly to httpx.AsyncClient.get(url) (line 72) with no intermediate security checks.
Source-to-Sink Chain
1. Entry Point (lines 52-70): fetch_feed() receives user-controlled url parameter with no validation.
2. HTTP Client (line 71): httpx.AsyncClient created with follow_redirects=True, amplifying SSRF risk.
3. Dangerous Sink (line 72): client.get(url) issues HTTP GET to...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| IBM/mcp-context-forge Product | < v1.0.7 | v1.0.7 |
Details and references
## Summary The mcp-rss-search module, an MCP server distributed as part of IBM/mcp-context-forge, contains a Server-Side Request Forgery (SSRF) vulnerability. The fetch_feed() method in RSSParser directly fetches attacker-controlled URLs via httpx without any SSRF protections — no private IP blocking, no DNS rebinding mitigation, no URL allowlisting, and no IP address validation. An attacker who can invoke the fetch_feed MCP tool can force the server to make HTTP requests to arbitrary internal network destinations, including cloud metadata services, internal APIs, and other private network resources. ## Details ## Root Cause The vulnerability exists because the fetch_feed() method in the RSSParser class (lines 52-96) performs no validation on the target URL before making an outbound HTTP request. ## Trust Boundary Failure The MCP protocol serves as a trust boundary between the caller and the server. The fetch_feed() method receives a url parameter from across this trust boundary and passes it directly to httpx.AsyncClient.get(url) (line 72) with no intermediate security checks. ## Source-to-Sink Chain 1. Entry Point (lines 52-70): fetch_feed() receives user-controlled url parameter with no validation. 2. HTTP Client (line 71): httpx.AsyncClient created with follow_redirects=True, amplifying SSRF risk. 3. Dangerous Sink (line 72): client.get(url) issues HTTP GET to attacker-controlled URL with no IP validation, no allowlisting, and no DNS rebinding protection. ## Missing Security Controls No ipaddress checks for private IPs. No DNS rebinding protection. No URL allowlisting. Core vulnerable code path: ```python # mcp-servers/python/mcp-rss-search/src/mcp_rss_search/server_fastmcp.py:52-96 async def fetch_feed(self, url: str, use_cache: bool = True) -> dict[str, Any]: try: if use_cache and url in self.cache: return self.cache[url] logger.info(f"Fetching RSS feed from {url}") async with httpx.AsyncClient(timeout=30.0, follow_redirects=True) as client: response = await client.get(url) response.raise_for_status() ``` Entry point and sink: user-controlled url parameter received via MCP protocol, passed directly to httpx.AsyncClient.get() with no SSRF protections — no private IP blocking, no allowlist, no DNS rebinding protection. ## POC ## Preconditions 1. The mcp-rss-search must be deployed and accessible via MCP protocol. 2. The attacker needs MCP tool invocation capability. ## Proof of Concept Step 1 (AWS Cloud Metadata): Call fetch_feed with url=http://169.254.169.254/latest/meta-data/ Step 2 (Internal Scan): Call fetch_feed with url=http://127.0.0.1:8080/ Expected: Server returns metadata or internal service responses, enabling network enumeration. ## Impact Cloud Credential Theft via metadata services. Internal Data Exposure from private APIs and databases. Network Reconnaissance through internal scanning.
- CVSS 3.1
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
- Severity from
- GitHub (reviewed advisory)
- Weakness
- CWE-918