SearXNG MCP Server: Unbounded Response Body Read Bypasses URL Size Limit in `web_url_read`
Date: 2026-06
Affected: npm/mcp-searxng
Attack vector: prompt-injection
Category: vulnerability-disclosure
Severity: High
CWE: CWE-400
CVSS: 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

## 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)** ```ts // 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-reade


Mitigations:

Architectural layers (MAESTRO):