[ ⌘K ]
← BACK TO SEARCH

mcpflow/lnd-mcp-server

critical

A Model Context Protocol (MCP) for querying Lightning Network node data using natural language.

MCP server (purpose undetermined)

purpose: MCP server (purpose undetermined)threat: network exposed
0May 20, 2026May 20, 2026GITHUB
5/20/2026
high1 finding
src/core/config/index.ts
211    logger.info(`Configuration loaded successfully: ${JSON.stringify(sanitizeConfig(config))}`);
src/index.ts:13src/composition.ts:10src/core/config/index.ts:211

// Exploitable if logs are accessible to an attacker (e.g., log aggregation service, shared logging system).

The configuration object is sanitized before logging, but the sanitizeConfig function only redacts string values for fields matching sensitive patterns. If a sensitive field contains a non-string value (e.g., an object or number), it may be logged in plaintext. Additionally, the sanitization relies on a static list of patterns and may miss new sensitive fields.

ImpactAn attacker with access to logs could obtain sensitive credentials such as TLS certificate paths, macaroon paths, LNC connection strings, or pairing phrases, leading to unauthorized access to the Lightning Network node.

FixEnsure all sensitive fields are redacted regardless of type. Use a more robust sanitization approach that recursively redacts any value under a sensitive key, and consider using a structured logging approach that never logs raw configuration objects.

high1 finding
src/core/config/index.ts
219    logger.error(`Failed to load configuration: ${sanitizedMessage}`);
src/index.ts:13src/composition.ts:10src/core/config/index.ts:219

// Exploitable if logs are accessible to an attacker.

The error message is sanitized before logging, but the sanitizeErrorMessage function uses regex patterns that may not cover all possible sensitive data formats. Additionally, the original error object is caught and its message is sanitized, but the stack trace (which may contain sensitive paths) is preserved in the sanitized error object and could be logged elsewhere.

ImpactSensitive file paths, environment variable values, or credentials could be exposed in error logs, aiding an attacker in reconnaissance or credential theft.

FixEnsure the sanitizeErrorMessage function is comprehensive and covers all known sensitive patterns. Consider stripping stack traces from error logs or sanitizing them as well.

medium1 finding
src/interfaces/mcp/McpServer.ts
156    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
157      try {
158        if (request.params.name === 'queryLightning') {
159          if (
160            !request.params.arguments ||
161            typeof request.params.arguments !== 'object' ||
162            typeof request.params.arguments.query !== 'string'
163          ) {
164            throw new McpError(ErrorCode.InvalidParams, 'Invalid query: expected a string in the query parameter');
165          }
166          const query = request.params.arguments.query;
167          const result = await this.lightningController.executeQuery(query);
168          return {
169            content: result.content,
170            data: result.data,
171            isError: result.isError,
172          };
173        } else {
174          throw new McpError(ErrorCode.MethodNotFound, `Tool ${request.params.name} not found`);
175        }
176      } catch (error) { ... }
src/index.ts:13src/composition.ts:19src/interfaces/mcp/McpServer.ts:156

// Exploitable if MCP is exposed to untrusted prompts or if the LLM is compromised.

The MCP server exposes a single tool 'queryLightning' that accepts an arbitrary natural language query string. The query is processed by an intent parser and domain handlers, which may allow querying any Lightning Network data (channels, balances, transactions, etc.) without granular access controls. The tool does not validate or restrict the scope of the query beyond the backend's own limitations.

ImpactA compromised LLM or unauthorized user could use the tool to query sensitive Lightning Network information, such as channel balances, routing history, or node identity, potentially leading to privacy breaches or financial reconnaissance.

FixImplement granular tools with specific, constrained capabilities (e.g., getBalance, listChannels) rather than a single generic query tool. Add authorization checks to ensure the caller is permitted to access the requested data.

medium1 finding
src/interfaces/mcp/McpServer.ts
162          if (
163            !request.params.arguments ||
164            typeof request.params.arguments !== 'object' ||
165            typeof request.params.arguments.query !== 'string'
166          ) {
167            throw new McpError(ErrorCode.InvalidParams, 'Invalid query: expected a string in the query parameter');
168          }
src/index.ts:13src/composition.ts:19src/interfaces/mcp/McpServer.ts:162

// Exploitable if downstream components are vulnerable to injection (e.g., if query is used in shell commands or SQL).

The only validation on the 'query' parameter is that it is a string. There is no length limit, no sanitization, and no restriction on the content of the query. This could allow injection attacks if the query is passed to subsystems that interpret it unsafely (e.g., shell commands, database queries).

ImpactAn attacker could craft a malicious query string that exploits vulnerabilities in downstream components (intent parser, domain handlers, or Lightning node interface), potentially leading to arbitrary command execution, data exfiltration, or denial of service.

FixAdd input validation: limit query length, restrict allowed characters, and sanitize the query before processing. Consider using a whitelist of allowed query patterns or intents.

low1 finding
src/core/config/index.ts
72function setupMockInfrastructure(): void {
73  if (process.env.CONNECTION_TYPE === 'mock') {
74    const mockDir = path.resolve(process.cwd(), 'mock');
75    const mockCertPath = path.resolve(mockDir, 'mock-cert.pem');
76    const mockMacaroonPath = path.resolve(mockDir, 'mock-macaroon');
77    if (!existsSync(mockDir)) {
78      mkdirSync(mockDir, { recursive: true });
79    }
80    if (!existsSync(mockCertPath)) {
81      writeFileSync(mockCertPath, 'MOCK TLS CERTIFICATE');
82      logger.debug(`Created mock TLS certificate at ${mockCertPath}`);
83    }
84    if (!existsSync(mockMacaroonPath)) {
85      writeFileSync(mockMacaroonPath, 'MOCK MACAROON');
86      logger.debug(`Created mock macaroon at ${mockMacaroonPath}`);
87    }
88    process.env.LND_TLS_CERT_PATH = mockCertPath;
89    process.env.LND_MACAROON_PATH = mockMacaroonPath;
90    logger.info('Using mock LND mode with generated certificate and macaroon');
91  }
92}
src/index.ts:13src/composition.ts:10src/core/config/index.ts:72

// Exploitable only if mock mode is enabled in a non-test environment or if the mock directory is exposed.

When using mock mode, the application creates predictable mock credential files (mock-cert.pem, mock-macaroon) in a known directory (./mock). These files contain static, non-random content. If mock mode is accidentally enabled in production or if the mock directory is accessible, an attacker could read these files and potentially use them to authenticate.

ImpactAn attacker with filesystem access could read the mock credentials and potentially authenticate to the Lightning node if mock mode is inadvertently used in a non-test environment.

FixEnsure mock mode is only enabled in development/test environments. Add a check to prevent mock mode in production. Use random, temporary credentials for mock mode and clean up after use.

85
LLM-based
low findings+5
high findings+50
medium findings+30