CVE-2026-58483
mcp-searxng: Unbounded Response Body Read Bypasses URL Size Limit in `web_url_read`
mcp-searxng is a Model Context Protocol server that gives AI assistants web search and URL-reading capabilities through SearXNG. Prior to 1.7.1, web_url_read in src/index.ts passes a caller-supplied URL to readUrlContent() in src/url-reader.ts, where checkContentLength() treats a missing Content-Length header as an inconclusive preflight and the normal and error paths then consume the complete body with response.text(). A server that omits Content-Length can therefore bypass URL_READ_MAX_CONTENT_LENGTH_BYTES and force unbounded memory use. The resulting string is also processed by NodeHtmlMarkdown.translate(), increasing CPU consumption and allowing an unauthenticated HTTP client to cause denial of service. This issue is fixed in version 1.7.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.5
mcp-searxng: Unbounded Response Body Read Bypasses URL Size Limit in `web_url_read`
mcp-searxng is a Model Context Protocol server that gives AI assistants web search and URL-reading capabilities through SearXNG. Prior to 1.7.1, web_url_read in src/index.ts passes a caller-supplied URL to readUrlContent() in src/url-reader.ts, where checkContentLength() treats a missing Content-Length header as an inconclusive preflight and the normal and error paths then consume the complete body with response.text(). A server that omits Content-Length can therefore bypass URL_READ_MAX_CONTENT_LENGTH_BYTES and force unbounded memory use. The resulting string is also processed by NodeHtmlMarkdown.translate(), increasing CPU consumption and allowing an unauthenticated HTTP client to cause denial of service. This issue is fixed in version 1.7.1.
- Record
CVE-2026-58483- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400
- Updated
- 2026-11-02
EUVDEUVD-2026-79124
7.5
mcp-searxng is a Model Context Protocol server that gives AI assistants web search and URL-reading capabilities through SearXNG. Prior to 1.7.1, web_url_read in src/index.ts passes a caller-supplied URL to readUrlContent() in src/url-reader.ts, where checkContentLength() treats a missing Content-Length header as an inconclusive preflight and the normal and error paths then consume the complete body with response.text(). A server that omits Content-Length can therefore bypass URL_READ_MAX_CONTENT_LENGTH_BYTES and force unbounded memory use. The resulting string is also processed by NodeHtmlMarkdown.translate(), increasing CPU consumption and allowing an unauthenticated HTTP client to cause denial of service. This issue is fixed in version 1.7.1.
- Record
EUVD-2026-79124- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-xcqx-9jf5-w339
7.5
SearXNG MCP Server: Unbounded Response Body Read Bypasses URL Size Limit in `web_url_read`
Unbounded Response Body Read Bypasses URL Size Limit in web_url_read
Summary
The web_url_read MCP tool in mcp-searxng enforces its 5 MiB response-size limit exclusively by inspecting the Content-Length header of a preliminary HEAD request. When a server omits Content-Length — a standard HTTP practice — checkContentLength() returns null, the guard condition short-circuits to false, and response.text() loads the entire response body into memory without any byte cap. An unauthenticated attacker who controls or can redirect to an HTTP endpoint can force the server process to consume unbounded memory and CPU, leading to a Denial of Service.
Details
web_url_read is the entry point (src/index.ts:226-240). It passes the caller-supplied URL directly into readUrlContent() in src/url-reader.ts.
Size-limit check (bypassed)
// src/url-reader.ts:352-360
const contentLength = await checkContentLength(...);
if (contentLength !== null && contentLength > maxContentLengthBytes) {
return createContentTooLargeMessage(contentLength, maxContentLengthBytes);
}
checkContentLength() (src/url-reader.ts:243-245) returns null when the HEAD response carries no Content-Length header. Because the guard uses the !== null conjunction, a null result causes the entire check to evaluate as false, and execution falls through without enforcing the configured 5 MiB ceiling.
Unbounded sinks
A full GET request is then issued (src/url-reader.ts:367) with no streaming byte cap:
// src/url-reader.ts:414 — normal response path
htmlContent = await response.text();
// src/url-reader.ts:402 — error response path (same issue)
responseBody = await response.text();
The full HTML string is subsequently passed to NodeHtmlMarkdown.translate() (src/url-reader.ts:429), which amplifies CPU consumption proportional to the body size.
Default exposure
web_url_read is enabled by default. In HTTP transport mode, authentication is disabled by default, so AV:N/PR:N applies unconditionally. In stdio mode, an attacker can trigger the path via prompt injection to cause the AI model to call the tool with an attacker-controlled URL.
PoC
Prerequisites
- Docker installed.
- Build context: the repository root (
npmAI_249_ihor-sokoliuk__mcp-searxng/).
Build the image
docker build \
-t vuln002-test \
-f vuln-002/Dockerfile \
reports/npmAI_249_ihor-sokoliuk__mcp-searxng/
Run the PoC
docker run --rm vuln002-test
The container starts two processes:
- A malicious HTTP server on
127.0.0.1:9799that responds to HEAD with HTTP 200 and noContent-Length, then responds to GET with a 6,291,456-byte HTML body and noContent-Length. - mcp-searxng in HTTP mode (
MCP_HTTP_ALLOW_PRIVATE_URLS=trueenables loopback URLs for local reproduction).
The PoC script initializes an MCP session and calls:
{
"method": "tools/call",
"params": {
"name": "web_url_read",
"arguments": { "url": "http://127.0.0.1:9799/", "maxLength": 1 }
}
}
Observed output (Phase 2 confirmation)
HEAD_REQUESTS : 1
GET_REQUESTS : 1
GET_BYTES_SENT : 6,291,456
CONFIGURED_DEFAULT_LIMIT : 5,242,880
BYTES_OVER_LIMIT : +1,048,576
ELAPSED_SEC : 0.17
TOOL_STATUS : SUCCESS
RETURNED_LENGTH_CHARS : 1
[PASS] VULNERABILITY CONFIRMED
6,291,456 bytes were transmitted to mcp-searxng despite a 5,242,880-byte (5 MiB) limit.
Root cause confirmed:
1. HEAD response had no Content-Length header.
2. checkContentLength() returned null (url-reader.ts:243-245)
3. Guard condition was false (null !== null => false) (url-reader.ts:359)
4. response.text() read 6,291,456 bytes without a cap (url-reader.ts:414)
Remediation
Replace both response.text() calls with a streaming reader that aborts once the byte counter exceeds…
- Record
GHSA-xcqx-9jf5-w339- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400
- Updated
- 2026-11-02
NVD
7.5
mcp-searxng is a Model Context Protocol server that gives AI assistants web search and URL-reading capabilities through SearXNG. Prior to 1.7.1, web_url_read in src/index.ts passes a caller-supplied URL to readUrlContent() in src/url-reader.ts, where checkContentLength() treats a missing Content-Length header as an inconclusive preflight and the normal and error paths then consume the complete body with response.text(). A server that omits Content-Length can therefore bypass URL_READ_MAX_CONTENT_LENGTH_BYTES and force unbounded memory use. The resulting string is also processed by NodeHtmlMarkdown.translate(), increasing CPU consumption and allowing an unauthenticated HTTP client to cause denial of service. This issue is fixed in version 1.7.1.
- Record
CVE-2026-58483- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400
- Updated
- 2026-11-02
OSV
7.5
mcp-searxng: Unbounded Response Body Read Bypasses URL Size Limit in `web_url_read`
mcp-searxng is a Model Context Protocol server that gives AI assistants web search and URL-reading capabilities through SearXNG. Prior to 1.7.1, web_url_read in src/index.ts passes a caller-supplied URL to readUrlContent() in src/url-reader.ts, where checkContentLength() treats a missing Content-Length header as an inconclusive preflight and the normal and error paths then consume the complete body with response.text(). A server that omits Content-Length can therefore bypass URL_READ_MAX_CONTENT_LENGTH_BYTES and force unbounded memory use. The resulting string is also processed by NodeHtmlMarkdown.translate(), increasing CPU consumption and allowing an unauthenticated HTTP client to cause denial of service. This issue is fixed in version 1.7.1.
- Record
CVE-2026-58483- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400
- Updated
- 2026-11-02
OSVGHSA-xcqx-9jf5-w339
7.5
SearXNG MCP Server: Unbounded Response Body Read Bypasses URL Size Limit in `web_url_read`
Unbounded Response Body Read Bypasses URL Size Limit in web_url_read
Summary
The web_url_read MCP tool in mcp-searxng enforces its 5 MiB response-size limit exclusively by inspecting the Content-Length header of a preliminary HEAD request. When a server omits Content-Length — a standard HTTP practice — checkContentLength() returns null, the guard condition short-circuits to false, and response.text() loads the entire response body into memory without any byte cap. An unauthenticated attacker who controls or can redirect to an HTTP endpoint can force the server process to consume unbounded memory and CPU, leading to a Denial of Service.
Details
web_url_read is the entry point (src/index.ts:226-240). It passes the caller-supplied URL directly into readUrlContent() in src/url-reader.ts.
Size-limit check (bypassed)
// src/url-reader.ts:352-360
const contentLength = await checkContentLength(...);
if (contentLength !== null && contentLength > maxContentLengthBytes) {
return createContentTooLargeMessage(contentLength, maxContentLengthBytes);
}
checkContentLength() (src/url-reader.ts:243-245) returns null when the HEAD response carries no Content-Length header. Because the guard uses the !== null conjunction, a null result causes the entire check to evaluate as false, and execution falls through without enforcing the configured 5 MiB ceiling.
Unbounded sinks
A full GET request is then issued (src/url-reader.ts:367) with no streaming byte cap:
// src/url-reader.ts:414 — normal response path
htmlContent = await response.text();
// src/url-reader.ts:402 — error response path (same issue)
responseBody = await response.text();
The full HTML string is subsequently passed to NodeHtmlMarkdown.translate() (src/url-reader.ts:429), which amplifies CPU consumption proportional to the body size.
Default exposure
web_url_read is enabled by default. In HTTP transport mode, authentication is disabled by default, so AV:N/PR:N applies unconditionally. In stdio mode, an attacker can trigger the path via prompt injection to cause the AI model to call the tool with an attacker-controlled URL.
PoC
Prerequisites
- Docker installed.
- Build context: the repository root (
npmAI_249_ihor-sokoliuk__mcp-searxng/).
Build the image
docker build \
-t vuln002-test \
-f vuln-002/Dockerfile \
reports/npmAI_249_ihor-sokoliuk__mcp-searxng/
Run the PoC
docker run --rm vuln002-test
The container starts two processes:
- A malicious HTTP server on
127.0.0.1:9799that responds to HEAD with HTTP 200 and noContent-Length, then responds to GET with a 6,291,456-byte HTML body and noContent-Length. - mcp-searxng in HTTP mode (
MCP_HTTP_ALLOW_PRIVATE_URLS=trueenables loopback URLs for local reproduction).
The PoC script initializes an MCP session and calls:
{
"method": "tools/call",
"params": {
"name": "web_url_read",
"arguments": { "url": "http://127.0.0.1:9799/", "maxLength": 1 }
}
}
Observed output (Phase 2 confirmation)
HEAD_REQUESTS : 1
GET_REQUESTS : 1
GET_BYTES_SENT : 6,291,456
CONFIGURED_DEFAULT_LIMIT : 5,242,880
BYTES_OVER_LIMIT : +1,048,576
ELAPSED_SEC : 0.17
TOOL_STATUS : SUCCESS
RETURNED_LENGTH_CHARS : 1
[PASS] VULNERABILITY CONFIRMED
6,291,456 bytes were transmitted to mcp-searxng despite a 5,242,880-byte (5 MiB) limit.
Root cause confirmed:
1. HEAD response had no Content-Length header.
2. checkContentLength() returned null (url-reader.ts:243-245)
3. Guard condition was false (null !== null => false) (url-reader.ts:359)
4. response.text() read 6,291,456 bytes without a cap (url-reader.ts:414)
Remediation
Replace both response.text() calls with a streaming reader that aborts once the byte counter exceeds…
- Record
GHSA-xcqx-9jf5-w339- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
mcp-searxngnpm |
before 1.7.1 | 1.7.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-58483 is a high vulnerability (CVSS 7.5) in Ihor-sokoliuk Mcp-searxng, published June 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.67%, the 52nd percentile. Fixed in mcp-searxng 1.7.1.
References
github.com/ihor-sokoliuk/mcp-searxng/security/advisories/GHSA-xcqx-9jf5-w339
github.com/ihor-sokoliuk/mcp-searxng/pull/121
github.com/ihor-sokoliuk/mcp-searxng/commit/f5a947ed1650daed10fbdcd53c0db5a86489ffe4
github.com/ihor-sokoliuk/mcp-searxng/releases/tag/v1.7.1
github.com/advisories/GHSA-xcqx-9jf5-w339
github.com/CVEProject/cvelistV5/tree/main/cves/2026/58xxx/CVE-2026-58483.json
nvd.nist.gov/vuln/detail/CVE-2026-58483
github.com/ihor-sokoliuk/mcp-searxng
Left out here: the rest of 2 source descriptions. The JSON record has them.