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
- Entry Point (lines 52-70): fetch_feed() receives user-controlled url parameter with no validation.
- HTTP Client (line 71): httpx.AsyncClient created with follow_redirects=True, amplifying SSRF risk.
- 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:
# 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
- The mcp-rss-search must be deployed and accessible via MCP protocol.
- 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.
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
Missing Security Controls
No ipaddress checks for private IPs. No DNS rebinding protection. No URL allowlisting.
Core vulnerable code path:
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
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.