CVE-2026-58485 Overview
CVE-2026-58485 is a Server-Side Request Forgery (SSRF) vulnerability in mcp-searxng, a Model Context Protocol (MCP) server that provides AI assistants with web search and URL-reading capabilities through SearXNG. Versions prior to 1.7.1 validate only the literal hostname of caller-supplied URLs before performing HTTP fetches. An attacker-controlled hostname that resolves via DNS to a private, loopback, link-local, or cloud-metadata address bypasses this lexical check. The MCP server then connects to the internal destination and returns the response to the caller. The issue is tracked under [CWE-918] and is fixed in version 1.7.1.
Critical Impact
Unauthenticated network clients in the default HTTP configuration can read internal services, exfiltrate credentials or service tokens, and enumerate reachable internal hosts through the web_url_read tool.
Affected Products
- mcp-searxng versions prior to 1.7.1
- Deployments exposing the MCP server over HTTP without MCP_HTTP_ALLOW_PRIVATE_URLS opt-out review
- STDIO deployments where prompt-influenced tool selection can supply attacker URLs
Discovery Timeline
- 2026-09-15 - CVE-2026-58485 published to the National Vulnerability Database (NVD)
- 2026-09-15 - Last updated in NVD database
Technical Details for CVE-2026-58485
Vulnerability Analysis
The web_url_read tool exposed by mcp-searxng accepts a caller-controlled URL through src/index.ts and passes it to assertUrlAllowed() in src/url-reader.ts. That function validates only the literal hostname string. After the lexical check passes, undiciFetch() performs operating-system DNS resolution independently and connects to whatever address is returned.
This design creates a time-of-check to time-of-use (TOCTOU) gap between hostname validation and network connection. A public-looking hostname such as attacker.example.com can be configured with an A record pointing to 169.254.169.254, 127.0.0.1, or an RFC 1918 address. The lexical filter does not detect this, and the fetch reaches the internal target.
In the default HTTP configuration, no authentication is required to invoke the tool. In STDIO deployments, an attacker can influence the AI assistant through prompt injection to select a malicious URL.
Root Cause
The root cause is incomplete SSRF mitigation. Direct private IP literals are blocked, but hostname validation is performed on the string alone without consulting DNS. The fetch layer resolves the hostname a second time and honors the resulting address without any private-range filtering.
Attack Vector
An attacker registers a hostname whose DNS resolves to a private, loopback, link-local, or cloud-metadata address. The attacker then instructs the MCP server, directly over HTTP or indirectly via a prompt-influenced AI client, to fetch a URL using that hostname. The server retrieves content from the internal target and returns it to the caller, exposing cloud metadata (for example, AWS IMDS at 169.254.169.254), internal admin panels, or service tokens.
// Patch: src/proxy.ts — DNS-aware lookup that rejects private addresses
import * as dns from "node:dns";
import { Agent, ProxyAgent } from "undici";
import { getHttpSecurityConfig } from "./http-security.js";
import { getConnectOptions } from "./tls-config.js";
import { createUrlSecurityPolicyDnsError, isPrivateAddress } from "./url-security.js";
type LookupCallback = (
err: NodeJS.ErrnoException | null,
address: string | dns.LookupAddress[],
family?: number,
) => void;
export function createUrlReaderLookup() {
return (hostname: string, options: dns.LookupOptions, callback: LookupCallback): void => {
if (getHttpSecurityConfig().allowPrivateUrls) {
(dns.lookup as any)(hostname, options, callback);
return;
}
dns.lookup(hostname, { ...options, all: true }, (error, addresses) => {
if (error) {
callback(error, options.all ? [] : "");
return;
}
if (addresses.length === 0) {
const notFound = new Error(`No DNS records found for ${hostname}`) as NodeJS.ErrnoException;
notFound.code = "ENOTFOUND";
callback(notFound, options.all ? [] : "");
return;
}
// Remaining logic filters resolved addresses through isPrivateAddress()
});
};
}
// Source: https://github.com/ihor-sokoliuk/mcp-searxng/commit/14575eaaa46a21391477d2b68673858ba6b52bd6
Detection Methods for CVE-2026-58485
Indicators of Compromise
- Outbound DNS queries from the mcp-searxng host that resolve to RFC 1918, loopback (127.0.0.0/8), link-local (169.254.0.0/16), or cloud metadata addresses.
- HTTP requests originating from the MCP server process directed at 169.254.169.254, metadata.google.internal, or internal service endpoints.
- Unexpected web_url_read tool invocations referencing unfamiliar external hostnames followed by connections to internal targets.
Detection Strategies
- Instrument undici fetches with logging that records both the requested hostname and the resolved IP address, then alert when the resolved address falls in a private range.
- Correlate MCP server access logs with egress firewall logs to identify tool calls that terminate at internal destinations.
- Review MCP prompt and tool-call telemetry for hostnames that were recently registered or use uncommon TLDs.
Monitoring Recommendations
- Log every web_url_read invocation including source client, requested URL, resolved IP, and HTTP status.
- Monitor for access attempts to cloud instance metadata endpoints from any container or host running the MCP server.
- Track version metadata across MCP server deployments to identify hosts still running versions below 1.7.1.
How to Mitigate CVE-2026-58485
Immediate Actions Required
- Upgrade mcp-searxng to version 1.7.1 or later on all deployments.
- Confirm that MCP_HTTP_ALLOW_PRIVATE_URLS is not set unless internal access is an intentional requirement.
- Restrict network egress from the MCP server so that only external destinations required by SearXNG are reachable.
Patch Information
The fix is delivered in mcp-searxng version 1.7.1. The patch introduces a custom undici DNS lookup handler that resolves the hostname, evaluates each returned address through isPrivateAddress(), and rejects the connection with a security policy error when any address falls in a private range. See the GitHub Security Advisory GHSA-mrvx-jmjw-vggc, the remediation commit, and the v1.7.1 release notes for complete details.
Workarounds
- Place the MCP server behind an egress proxy configured to block RFC 1918, loopback, link-local, and cloud metadata addresses.
- Require authentication on the HTTP transport and restrict callers to trusted networks until the upgrade is applied.
- Disable or gate the web_url_read tool in STDIO deployments where prompt injection from untrusted content is possible.
# Verify installed version and remove the private-URL opt-out if present
npm ls mcp-searxng
npm install mcp-searxng@1.7.1
# Ensure the opt-out environment variable is not set in the deployment
unset MCP_HTTP_ALLOW_PRIVATE_URLS
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

