Skip to content

Server-Side Request Forgery (SSRF) in mcp-rss-search via Unvalidated URL Fetching

High
brian-hussey published GHSA-578v-pgw5-36gv Aug 25, 2026

Package

IBM/mcp-context-forge (self-hosted)

Affected versions

v1.0.5

Patched versions

>=v1.0.7

Description

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:

# 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.

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Changed
Confidentiality
High
Integrity
None
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N

CVE ID

No known CVE

Weaknesses

Server-Side Request Forgery (SSRF)

The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. Learn more on MITRE.

Credits