hyeongjun-dev/metabase-mcp-server
criticalA Model Context Protocol server that integrates AI assistants with Metabase analytics platform
MCP server (purpose undetermined)
202 this.logDebug(`Making request to ${url.toString()}`);
203 this.logDebug(`Using headers: ${JSON.stringify(headers)}`);// Exploitable if debug logging is enabled and logs are accessible to an attacker.
The server logs HTTP headers in debug mode, which include the X-API-KEY or X-Metabase-Session token. If debug logging is enabled, credentials could be exposed in logs.
ImpactAn attacker with access to logs could retrieve Metabase API keys or session tokens, leading to unauthorized access to Metabase.
FixRemove logging of sensitive headers, or ensure debug logging is disabled in production and logs are securely stored.
232 this.logInfo('Using API Key authentication', {
233 keyLength: this.apiKey.length,
234 keyFormat: this.apiKey.includes('mb_') ? 'starts with mb_' : 'other format'
235 });// Exploitable if logs are accessible.
The server logs the length and format of the API key, which can aid an attacker in brute-forcing or identifying the key type.
ImpactInformation leakage that could assist in compromising the API key.
FixRemove logging of API key metadata.
648 const queryData = {
649 type: "native",
650 native: {
651 query: query,
652 template_tags: {}
653 },
654 parameters: nativeParameters,
655 database: databaseId
656 };
657
658 const response = await this.request<any>('/api/dataset', {
659 method: 'POST',
660 body: JSON.stringify(queryData)
661 });// Exploitable if MCP is exposed to untrusted prompts or if LLM is compromised.
The execute_query tool accepts a raw SQL query string from the user and sends it directly to the Metabase API without any sanitization or validation. This allows the LLM to execute arbitrary SQL queries on the Metabase database, which is beyond the intended purpose of simply retrieving data from Metabase.
ImpactAn attacker (via compromised LLM) could execute arbitrary SQL queries, potentially reading, modifying, or deleting data in the underlying database, depending on Metabase permissions.
FixRestrict the execute_query tool to only allow SELECT queries, or implement a query builder that limits operations. Alternatively, remove the tool if not needed.
574 case "execute_card": {
575 const cardId = request.params?.arguments?.card_id;
576 if (!cardId) {
577 this.logWarn('Missing card_id parameter in execute_card request', { requestId });
578 throw new McpError(
579 ErrorCode.InvalidParams,
580 "Card ID parameter is required"
581 );
582 }
583
584 this.logDebug(`Executing card with ID: ${cardId}`);
585 const parameters = request.params?.arguments?.parameters || {};
586
587 const response = await this.request<any>(`/api/card/${cardId}/query`, {// Exploitable if Metabase API has vulnerabilities or if IDs are used unsafely.
The server does not validate that card_id, dashboard_id, or database_id are positive integers. Although the schema specifies 'number', the actual value is used directly in URL path construction. An attacker could pass non-numeric values, potentially leading to path traversal or SSRF if the Metabase API has such vulnerabilities.
ImpactPotential path traversal or SSRF against the Metabase API, though limited by the API's own validation.
FixValidate that IDs are positive integers before using them in URLs.