GHSA-hjwh-xvfw-qrwj: Mcp searxng SearXNG Basic Authentication Credentials Exposed Vulnerability

MODERATE
CVSS 5.5
CWE-532 CWE-209
Published
Advisory Summary

GHSA-hjwh-xvfw-qrwj is a MODERATE (CVSS 5.5) searxng basic authentication credentials exposed vulnerability (CWE-532: Insertion of Sensitive Information into Log File) affecting Mcp searxng libraries in the npm ecosystem. The issue involves searxng basic authentication credentials exposed through mcp logs and json-rpc error responses. Remediation is available by upgrading affected packages to version 1.12.0.

GHSA-hjwh-xvfw-qrwj at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-hjwh-xvfw-qrwj
Severity MODERATE
CVSS v3.1 Base Score 5.5
CWE Classification CWE-532: Insertion of Sensitive Information into Log File
Affected Product Mcp searxng
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 5.5

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N).

Attack Vector Local (AV:L)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity None (I:N)
Availability None (A:N)

How to Fix GHSA-hjwh-xvfw-qrwj

To remediate this vulnerability, upgrade all affected Mcp searxng dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

mcp-searxng fixed: 1.12.0
npm install mcp-searxng@1.12.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls mcp-searxng

How to Check if You Are Affected

To determine whether your Node.js application is affected by GHSA-hjwh-xvfw-qrwj, inspect your project dependencies using npm:

npm ls mcp-searxng

Analyze the terminal output to locate any version of Mcp searxng in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.12.0), your application is affected.

Note: The npm ls mcp-searxng command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-532: Insertion of Sensitive Information into Log File, where the product writes sensitive information to a log file. In Mcp searxng, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary mcp-searxng version 1.11.0 exposes SearXNG Basic Authentication credentials embedded in the `SEARXNG_URL` environment variable. When the server starts in STDIO mode and an MCP client connects, the complete `SEARXNG_URL`, including its username and password, is sent to the client through an MCP `notifications/message` logging notification. Additionally, when URL validation fails, the complete credential-bearing URL is included in the configuration error. This error is logged through MCP and returned to the client as a JSON-RPC error response. For example, a value such as: ```text http://username:password@searxng.example.com ``` is exposed without redaction. A connected MCP client or anyone with access to captured server logs may recover the SearXNG credentials and use them to access the configured SearXNG instance. The issue was confirmed in: ```text mcp-searxng 1.11.0 ``` Suggested severity: **Medium** ### Details mcp-searxng supports SearXNG Basic Authentication by embedding credentials in the URL userinfo component: ```text https://username:password@searxng.example.com ``` The project contains a redaction function named `redactSearxngInstanceUrl()`, but it is not used in several logging and error-handling paths. #### Startup console disclosure In `src/index.ts:373-378`, the server retrieves the raw SearXNG URLs and writes them directly to stderr: ```typescript const searxngInstances = getSearxngInstances(); if (searxngInstances.length > 0) { console.error(`🌐 SearXNG URLs: ${searxngInstances.join("; ")}`); } ``` `getSearxngInstances()` returns the unmodified environment-variable values. Relevant code in `src/searxng-instances.ts:25-38`: ```typescript export function parseSearxngUrls( raw: string | undefined = process.env.SEARXNG_URL ): string[] { if (raw === undefined) { return []; } return raw .split(";") .map((entry) => entry.trim()) .filter((entry) => entry !== ""); } export function getSearxngInstances(): string[] { return parseSearxngUrls(); } ``` #### MCP logging notification disclosure After the MCP client connects, `src/index.ts:388-393` sends the complete URL through the MCP logging interface: ```typescript const searxngInstances = getSearxngInstances(); logMessage( mcpServer, "info", `SearXNG URLs: ${ searxngInstances.length > 0 ? searxngInstances.join("; ") : "not configured" }` ); ``` `logMessage()` passes this value to `sendLoggingMessage()` in `src/logging.ts:15-25`: ```typescript mcpServer.sendLoggingMessage({ level, data: notificationData }); ``` As a result, the connected MCP client receives a message containing the username and password: ```json { "method": "notifications/message", "params": { "level": "info", "data": { "message": "SearXNG URLs: http://username:password@searxng.example.com" } }, "jsonrpc": "2.0" } ``` #### Configuration error disclosure The URL validation function includes the complete unredacted value in error messages. Relevant code in `src/searxng-instances.ts:44-52`: ```typescript export function validateSearxngInstanceUrl( value: string ): string | null { try { const url = new URL(value); if (!["http:", "https:"].includes(url.protocol)) { return `SEARXNG_URL invalid protocol for "${value}": ${url.protocol}`; } } catch { return `SEARXNG_URL invalid format: ${value}`; } return null; } ``` The validation error is aggregated by `validateEnvironment()` in `src/error-handler.ts:175-203`: ```typescript const validationError = validateSearxngInstanceUrl(searxngUrl); if (validationError) { issues.push(validationError); } ``` The complete error is then thrown from `src/search.ts:689-693`: ```typescript const validationError = validateEnvironment(); if (validationError) { logMessage(mcpServer, "error", "Configuration invalid"); throw new MCPSearXNGError(validationError); } ``` The tool handler in `src/index.ts:254-260` sends the error message and stack trace through MCP logging, then rethrows it: ```typescript logMessage( mcpServer, "error", `Tool execution error: ${ error instanceof Error ? error.message : String(error) }`, { tool: name, args: args, error: error instanceof Error ? error.stack : String(error) } ); throw error; ``` Rethrowing the error causes the same unredacted credential-bearing URL to be returned in the JSON-RPC error response. #### Existing redaction function is not used The project already contains a suitable redaction function in `src/searxng-instances.ts:57-69`: ```typescript export function redactSearxngInstanceUrl( raw: string ): string { try { const url = new URL(raw); if (!url.username && !url.password) { return raw; } url.username = ""; url.password = ""; return url.toString(); } catch { return raw.replace( /^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)[^/]*@/, "$1" ); } } ``` However, this function is not applied before startup logging, MCP logging, or configuration error construction. The MCP manifest also marks `SEARXNG_URL` as non-secret in `.mcp/server.json:20-25`: ```json { "name": "SEARXNG_URL", "description": "URL of your SearXNG instance", "isRequired": true, "isSecret": false, "format": "string" } ``` Because credentials may be embedded in this variable, it should be classified as a secret. ### PoC The following proof of concept uses fake credentials. A real SearXNG server is not required. #### Requirements ```text Node.js 20 or newer npm mcp-searxng 1.11.0 source code ``` #### Build the application ```bash unzip mcp-searxng-main.zip cd mcp-searxng-main npm ci npm run build ``` #### Test 1: Credential disclosure through MCP logging Create an MCP initialization request: ```bash cat > /tmp/mcp-init.jsonl <<'EOF' {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"credential-leak-poc","version":"1.0.0"}}} EOF ``` Start the server with fake credentials embedded in a valid HTTP URL: ```bash SEARXNG_URL='http://MCP_POC_USER_7391:MCP_POC_PASS_7391@127.0.0.1:9' \ timeout 8s node dist/cli.js \ < /tmp/mcp-init.jsonl \ 2>&1 | tee credential-log-leak.txt ``` Search the output for the credentials: ```bash grep -nE \ 'MCP_POC_USER_7391|MCP_POC_PASS_7391' \ credential-log-leak.txt ``` #### Observed result The complete credential-bearing URL is exposed: ```text SearXNG URLs: http://MCP_POC_USER_7391:MCP_POC_PASS_7391@127.0.0.1:9 ``` It is also delivered to the MCP client: ```json { "method": "notifications/message", "params": { "level": "info", "data": { "message": "SearXNG URLs: http://MCP_POC_USER_7391:MCP_POC_PASS_7391@127.0.0.1:9" } }, "jsonrpc": "2.0" } ``` This confirms that a connected MCP client can recover the configured username and password without accessing the host environment. #### Test 2: Credential disclosure through JSON-RPC errors Create initialization and tool-call requests: ```bash cat > /tmp/mcp-error-poc.jsonl <<'EOF' {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"credential-error-poc","version":"1.0.0"}}} {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"searxng_web_search","arguments":{"query":"credential leak test"}}} EOF ``` Start the server with a credential-bearing URL that uses an unsupported protocol: ```bash SEARXNG_URL='ftp://MCP_POC_USER_7391:MCP_POC_PASS_7391@example.invalid' \ timeout 8s node dist/cli.js \ < /tmp/mcp-error-poc.jsonl \ 2>&1 | tee credential-error-leak.txt ``` Search the response: ```bash grep -nE \ 'MCP_POC_USER_7391|MCP_POC_PASS_7391' \ credential-error-leak.txt ``` #### Observed result The complete URL is exposed in the MCP logging notification: ```text Tool execution error: Configuration Issues: SEARXNG_URL invalid protocol for "ftp://MCP_POC_USER_7391:MCP_POC_PASS_7391@example.invalid": ftp: ``` It is also returned directly in the JSON-RPC error: ```json { "jsonrpc": "2.0", "id": 2, "error": { "code": -32603, "message": "Configuration Issues: SEARXNG_URL invalid protocol for \"ftp://MCP_POC_USER_7391:MCP_POC_PASS_7391@example.invalid\": ftp:" } } ``` The raw username and password are therefore exposed through both logging and protocol responses. ### Impact This is a sensitive credential disclosure vulnerability. The following parties may obtain the credentials: 1. A connected MCP client receiving logging notifications. 2. A client capable of invoking a tool and receiving JSON-RPC errors. 3. A user or process with access to captured stderr output. 4. A centralized logging or monitoring system collecting application logs. 5. Other users with access to shared log files or container logs. The exposed credentials may allow an attacker to authenticate directly to the configured SearXNG instance. Depending on the SearXNG deployment and the permissions associated with the account, this may allow: 1. Unauthorized use of a private SearXNG service. 2. Access to functionality restricted through Basic Authentication. 3. Consumption of private server resources. 4. Exposure of information available only to authenticated users. 5. Further account compromise where the credentials have been reused. The default STDIO transport limits the exposure to the connected parent MCP client and local logging environment. However, MCP clients should not receive upstream service credentials, and the project security documentation explicitly treats credentials embedded in `SEARXNG_URL` as secrets that must be redacted. ### Suggested mitigation Apply `redactSearxngInstanceUrl()` before including any SearXNG URL in console or MCP logging: ```typescript const redactedInstances = getSearxngInstances() .map(redactSearxngInstanceUrl); logMessage( mcpServer, "info", `SearXNG URLs: ${ redactedInstances.length > 0 ? redactedInstances.join("; ") : "not configured" }` ); ``` Do not include raw configuration values in validation errors. A generic error can be returned instead: ```typescript return `SEARXNG_URL entry has an unsupported protocol: ${url.protocol}`; ``` For malformed URLs: ```typescript return "SEARXNG_URL contains an invalid URL"; ``` The following additional changes are recommended: 1. Redact URLs before writing them to stderr. 2. Redact secrets before sending MCP logging notifications. 3. Avoid including raw environment-variable values in exceptions. 4. Avoid returning detailed stack traces containing secrets to MCP clients. 5. Mark `SEARXNG_URL` as secret in `.mcp/server.json`: ```json "isSecret": true ``` 6. Add regression tests that assert usernames and passwords never appear in: * stderr output * MCP logging notifications * JSON-RPC error responses * stack traces * configuration resources

GHSA-hjwh-xvfw-qrwj Affected Mcp searxng Versions

1 component(s)
Fixed Versions:
1.12.0
Product / Package Ecosystem Affected Versions Fixed Version
mcp-searxng
npm
< 1.12.0
1.12.0

References

Frequently Asked Questions

What is GHSA-hjwh-xvfw-qrwj?
GHSA-hjwh-xvfw-qrwj is a security vulnerability in Mcp searxng involving SearXNG Basic Authentication Credentials Exposed Through MCP Logs and JSON-RPC Error Responses under CWE-532: Insertion of Sensitive Information into Log File.
Which Mcp searxng versions are affected?
Affected versions include releases prior to 1.12.0 across affected packages: mcp-searxng.
What version fixes GHSA-hjwh-xvfw-qrwj?
Upgrading to 1.12.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is mcp-searxng affected?
Yes, mcp-searxng is affected in releases prior to 1.12.0. Upgrade your dependency to 1.12.0 or later.
What is the CVSS score of GHSA-hjwh-xvfw-qrwj?
GHSA-hjwh-xvfw-qrwj has a CVSS v3.1 base score of 5.5 (MODERATE) with vector string CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N.
What CWE is associated with GHSA-hjwh-xvfw-qrwj?
GHSA-hjwh-xvfw-qrwj is classified under CWE-532: Insertion of Sensitive Information into Log File (The product writes sensitive information to a log file.).
How can I check npm dependencies for GHSA-hjwh-xvfw-qrwj?
Run the dependency tree command: 'npm ls mcp-searxng'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-hjwh-xvfw-qrwj",
  "modified" : "2026-08-19T19:32:46Z",
  "published" : "2026-08-19T19:32:46Z",
  "aliases" : [ ],
  "summary" : "SearXNG Basic Authentication Credentials Exposed Through MCP Logs and JSON-RPC Error Responses",
  "details" : "### Summary\n\nmcp-searxng version 1.11.0 exposes SearXNG Basic Authentication credentials embedded in the `SEARXNG_URL` environment variable.\n\nWhen the server starts in STDIO mode and an MCP client connects, the complete `SEARXNG_URL`, including its username and password, is sent to the client through an MCP `notifications/message` logging notification.\n\nAdditionally, when URL validation fails, the complete credential-bearing URL is included in the configuration error. This error is logged through MCP and returned to the client as a JSON-RPC error response.\n\nFor example, a value such as:\n\n```text\nhttp://username:password@searxng.example.com\n```\n\nis exposed without redaction.\n\nA connected MCP client or anyone with access to captured server logs may recover the SearXNG credentials and use them to access the configured SearXNG instance.\n\nThe issue was confirmed in:\n\n```text\nmcp-searxng 1.11.0\n```\n\nSuggested severity: **Medium**\n\n### Details\n\nmcp-searxng supports SearXNG Basic Authentication by embedding credentials in the URL userinfo component:\n\n```text\nhttps://username:password@searxng.example.com\n```\n\nThe project contains a redaction function named `redactSearxngInstanceUrl()`, but it is not used in several logging and error-handling paths.\n\n#### Startup console disclosure\n\nIn `src/index.ts:373-378`, the server retrieves the raw SearXNG URLs and writes them directly to stderr:\n\n```typescript\nconst searxngInstances = getSearxngInstances();\n\nif (searxngInstances.length > 0) {\n  console.error(`🌐 SearXNG URLs: ${searxngInstances.join(\"; \")}`);\n}\n```\n\n`getSearxngInstances()` returns the unmodified environment-variable values.\n\nRelevant code in `src/searxng-instances.ts:25-38`:\n\n```typescript\nexport function parseSearxngUrls(\n  raw: string | undefined = process.env.SEARXNG_URL\n): string[] {\n  if (raw === undefined) {\n    return [];\n  }\n\n  return raw\n    .split(\";\")\n    .map((entry) => entry.trim())\n    .filter((entry) => entry !== \"\");\n}\n\nexport function getSearxngInstances(): string[] {\n  return parseSearxngUrls();\n}\n```\n\n#### MCP logging notification disclosure\n\nAfter the MCP client connects, `src/index.ts:388-393` sends the complete URL through the MCP logging interface:\n\n```typescript\nconst searxngInstances = getSearxngInstances();\n\nlogMessage(\n  mcpServer,\n  \"info\",\n  `SearXNG URLs: ${\n    searxngInstances.length > 0\n      ? searxngInstances.join(\"; \")\n      : \"not configured\"\n  }`\n);\n```\n\n`logMessage()` passes this value to `sendLoggingMessage()` in `src/logging.ts:15-25`:\n\n```typescript\nmcpServer.sendLoggingMessage({\n  level,\n  data: notificationData\n});\n```\n\nAs a result, the connected MCP client receives a message containing the username and password:\n\n```json\n{\n  \"method\": \"notifications/message\",\n  \"params\": {\n    \"level\": \"info\",\n    \"data\": {\n      \"message\": \"SearXNG URLs: http://username:password@searxng.example.com\"\n    }\n  },\n  \"jsonrpc\": \"2.0\"\n}\n```\n\n#### Configuration error disclosure\n\nThe URL validation function includes the complete unredacted value in error messages.\n\nRelevant code in `src/searxng-instances.ts:44-52`:\n\n```typescript\nexport function validateSearxngInstanceUrl(\n  value: string\n): string | null {\n  try {\n    const url = new URL(value);\n\n    if (![\"http:\", \"https:\"].includes(url.protocol)) {\n      return `SEARXNG_URL invalid protocol for \"${value}\": ${url.protocol}`;\n    }\n  } catch {\n    return `SEARXNG_URL invalid format: ${value}`;\n  }\n\n  return null;\n}\n```\n\nThe validation error is aggregated by `validateEnvironment()` in `src/error-handler.ts:175-203`:\n\n```typescript\nconst validationError =\n  validateSearxngInstanceUrl(searxngUrl);\n\nif (validationError) {\n  issues.push(validationError);\n}\n```\n\nThe complete error is then thrown from `src/search.ts:689-693`:\n\n```typescript\nconst validationError = validateEnvironment();\n\nif (validationError) {\n  logMessage(mcpServer, \"error\", \"Configuration invalid\");\n  throw new MCPSearXNGError(validationError);\n}\n```\n\nThe tool handler in `src/index.ts:254-260` sends the error message and stack trace through MCP logging, then rethrows it:\n\n```typescript\nlogMessage(\n  mcpServer,\n  \"error\",\n  `Tool execution error: ${\n    error instanceof Error\n      ? error.message\n      : String(error)\n  }`,\n  {\n    tool: name,\n    args: args,\n    error:\n      error instanceof Error\n        ? error.stack\n        : String(error)\n  }\n);\n\nthrow error;\n```\n\nRethrowing the error causes the same unredacted credential-bearing URL to be returned in the JSON-RPC error response.\n\n#### Existing redaction function is not used\n\nThe project already contains a suitable redaction function in `src/searxng-instances.ts:57-69`:\n\n```typescript\nexport function redactSearxngInstanceUrl(\n  raw: string\n): string {\n  try {\n    const url = new URL(raw);\n\n    if (!url.username && !url.password) {\n      return raw;\n    }\n\n    url.username = \"\";\n    url.password = \"\";\n    return url.toString();\n  } catch {\n    return raw.replace(\n      /^([a-zA-Z][a-zA-Z0-9+.-]*:\\/\\/)[^/]*@/,\n      \"$1\"\n    );\n  }\n}\n```\n\nHowever, this function is not applied before startup logging, MCP logging, or configuration error construction.\n\nThe MCP manifest also marks `SEARXNG_URL` as non-secret in `.mcp/server.json:20-25`:\n\n```json\n{\n  \"name\": \"SEARXNG_URL\",\n  \"description\": \"URL of your SearXNG instance\",\n  \"isRequired\": true,\n  \"isSecret\": false,\n  \"format\": \"string\"\n}\n```\n\nBecause credentials may be embedded in this variable, it should be classified as a secret.\n\n### PoC\n\nThe following proof of concept uses fake credentials. A real SearXNG server is not required.\n\n#### Requirements\n\n```text\nNode.js 20 or newer\nnpm\nmcp-searxng 1.11.0 source code\n```\n\n#### Build the application\n\n```bash\nunzip mcp-searxng-main.zip\ncd mcp-searxng-main\n\nnpm ci\nnpm run build\n```\n\n#### Test 1: Credential disclosure through MCP logging\n\nCreate an MCP initialization request:\n\n```bash\ncat > /tmp/mcp-init.jsonl <<'EOF'\n{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"credential-leak-poc\",\"version\":\"1.0.0\"}}}\nEOF\n```\n\nStart the server with fake credentials embedded in a valid HTTP URL:\n\n```bash\nSEARXNG_URL='http://MCP_POC_USER_7391:MCP_POC_PASS_7391@127.0.0.1:9' \\\ntimeout 8s node dist/cli.js \\\n< /tmp/mcp-init.jsonl \\\n2>&1 | tee credential-log-leak.txt\n```\n\nSearch the output for the credentials:\n\n```bash\ngrep -nE \\\n'MCP_POC_USER_7391|MCP_POC_PASS_7391' \\\ncredential-log-leak.txt\n```\n\n#### Observed result\n\nThe complete credential-bearing URL is exposed:\n\n```text\nSearXNG URLs: http://MCP_POC_USER_7391:MCP_POC_PASS_7391@127.0.0.1:9\n```\n\nIt is also delivered to the MCP client:\n\n```json\n{\n  \"method\": \"notifications/message\",\n  \"params\": {\n    \"level\": \"info\",\n    \"data\": {\n      \"message\": \"SearXNG URLs: http://MCP_POC_USER_7391:MCP_POC_PASS_7391@127.0.0.1:9\"\n    }\n  },\n  \"jsonrpc\": \"2.0\"\n}\n```\n\nThis confirms that a connected MCP client can recover the configured username and password without accessing the host environment.\n\n#### Test 2: Credential disclosure through JSON-RPC errors\n\nCreate initialization and tool-call requests:\n\n```bash\ncat > /tmp/mcp-error-poc.jsonl <<'EOF'\n{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"credential-error-poc\",\"version\":\"1.0.0\"}}}\n{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"searxng_web_search\",\"arguments\":{\"query\":\"credential leak test\"}}}\nEOF\n```\n\nStart the server with a credential-bearing URL that uses an unsupported protocol:\n\n```bash\nSEARXNG_URL='ftp://MCP_POC_USER_7391:MCP_POC_PASS_7391@example.invalid' \\\ntimeout 8s node dist/cli.js \\\n< /tmp/mcp-error-poc.jsonl \\\n2>&1 | tee credential-error-leak.txt\n```\n\nSearch the response:\n\n```bash\ngrep -nE \\\n'MCP_POC_USER_7391|MCP_POC_PASS_7391' \\\ncredential-error-leak.txt\n```\n\n#### Observed result\n\nThe complete URL is exposed in the MCP logging notification:\n\n```text\nTool execution error: Configuration Issues: SEARXNG_URL invalid protocol for \"ftp://MCP_POC_USER_7391:MCP_POC_PASS_7391@example.invalid\": ftp:\n```\n\nIt is also returned directly in the JSON-RPC error:\n\n```json\n{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 2,\n  \"error\": {\n    \"code\": -32603,\n    \"message\": \"Configuration Issues: SEARXNG_URL invalid protocol for \\\"ftp://MCP_POC_USER_7391:MCP_POC_PASS_7391@example.invalid\\\": ftp:\"\n  }\n}\n```\n\nThe raw username and password are therefore exposed through both logging and protocol responses.\n\n### Impact\n\nThis is a sensitive credential disclosure vulnerability.\n\nThe following parties may obtain the credentials:\n\n1. A connected MCP client receiving logging notifications.\n2. A client capable of invoking a tool and receiving JSON-RPC errors.\n3. A user or process with access to captured stderr output.\n4. A centralized logging or monitoring system collecting application logs.\n5. Other users with access to shared log files or container logs.\n\nThe exposed credentials may allow an attacker to authenticate directly to the configured SearXNG instance.\n\nDepending on the SearXNG deployment and the permissions associated with the account, this may allow:\n\n1. Unauthorized use of a private SearXNG service.\n2. Access to functionality restricted through Basic Authentication.\n3. Consumption of private server resources.\n4. Exposure of information available only to authenticated users.\n5. Further account compromise where the credentials have been reused.\n\nThe default STDIO transport limits the exposure to the connected parent MCP client and local logging environment. However, MCP clients should not receive upstream service credentials, and the project security documentation explicitly treats credentials embedded in `SEARXNG_URL` as secrets that must be redacted.\n\n### Suggested mitigation\n\nApply `redactSearxngInstanceUrl()` before including any SearXNG URL in console or MCP logging:\n\n```typescript\nconst redactedInstances = getSearxngInstances()\n  .map(redactSearxngInstanceUrl);\n\nlogMessage(\n  mcpServer,\n  \"info\",\n  `SearXNG URLs: ${\n    redactedInstances.length > 0\n      ? redactedInstances.join(\"; \")\n      : \"not configured\"\n  }`\n);\n```\n\nDo not include raw configuration values in validation errors. A generic error can be returned instead:\n\n```typescript\nreturn `SEARXNG_URL entry has an unsupported protocol: ${url.protocol}`;\n```\n\nFor malformed URLs:\n\n```typescript\nreturn \"SEARXNG_URL contains an invalid URL\";\n```\n\nThe following additional changes are recommended:\n\n1. Redact URLs before writing them to stderr.\n2. Redact secrets before sending MCP logging notifications.\n3. Avoid including raw environment-variable values in exceptions.\n4. Avoid returning detailed stack traces containing secrets to MCP clients.\n5. Mark `SEARXNG_URL` as secret in `.mcp/server.json`:\n\n```json\n\"isSecret\": true\n```\n\n6. Add regression tests that assert usernames and passwords never appear in:\n\n   * stderr output\n   * MCP logging notifications\n   * JSON-RPC error responses\n   * stack traces\n   * configuration resources",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "mcp-searxng"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "1.12.0"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/ihor-sokoliuk/mcp-searxng/security/advisories/GHSA-hjwh-xvfw-qrwj"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/ihor-sokoliuk/mcp-searxng"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/ihor-sokoliuk/mcp-searxng/releases/tag/v1.12.0"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-209", "CWE-532" ],
    "severity" : "MODERATE",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-08-19T19:32:46Z",
    "nvd_published_at" : null
  }
}