GHSA-jj54-r8gm-2fcf: dbt MCP Server Transmits All MCP Tool Arguments Including Raw SQL and --vars Credentials to dbt Labs Telemetry by Default Without Redaction
*Discovered through manual source code review. Verified by PoC execution against a local dbt-mcp v1.15.1 installation.*Summary`DefaultUsageTracker.emit_tool_called_event()` in `src/dbt_mcp/tracking/tracking.py` serializes the complete `arguments` dictionary of every MCP tool call and transmits it verbatim to the dbt Labs telemetry service via `dbtlabs_vortex.producer.log_proto`. No field is redacted, truncated, or excluded before transmission. This includes the `sql_query` parameter of the `show` tool (arbitrary SQL) and the `vars` parameter of `run`, `build`, and `test` (JSON string that may contain credentials). Telemetry is **on by default**; the opt-out mechanism requires explicit user action and is not surfaced during installation.Details**Serialization code (`tracking.py` lines 101–103):**Every key-value pair in `arguments` is JSON-serialized into `arguments_mapping` and passed to `log_proto(ToolCalled(...))`. There is no allowlist of safe fields, no blocklist of sensitive fields, and no truncation.**Default opt-out state (`settings.py` lines 210–231):**Tracking is active unless the user has explicitly set `DBT_SEND_ANONYMOUS_USAGE_STATS=false` or `DO_NOT_TRACK=1`. Neither of these env vars is required or mentioned during `pip install dbt-mcp` or MCP configuration.**Arguments containing sensitive data by tool:**| Tool | Parameter | Example sensitive content |
|------|-----------|--------------------------|
| `show` | `sql_query` | `SELECT ssn, salary FROM customers` |
| `run`, `build`, `test` | `vars` | `{"db_password": "s3cr3t", "api_key": "sk-..."}` |
| `compile`, `list`, all | `node_selection` | Internal model names, data topology |PoC**1. Serialization demonstration — shows the exact payload sent to `log_proto`:****2. Network-level verification (optional, requires mitmproxy):**To confirm the payload reaches the dbt Labs telemetry endpoint, intercept outbound HTTPS traffic from a running dbt-mcp instance:The `arguments` field in the captured protobuf will contain the verbatim serialized payload shown above.**Step 2 is provided for reference only and was not executed as part of this submission. Step 1 fully demonstrates the serialization behavior.**Screenshot from testingImpact**Directly proven by this PoC:**Every key-value pair in every MCP tool call's `arguments` dict is JSON-serialized and included in the payload passed to `log_proto(ToolCalled(...))`.This behavior is active by default with no user action required.Affected tools include `show` (`sql_query`), `run`/`build`/`test` (`vars`, `node_selection`), `compile` (`node_selection`), and any future tool whose arguments contain sensitive data.**Compliance and privacy implications:** Organizations processing personally identifiable information (PII) or regulated data through the `show` tool (e.g., ad-hoc SQL queries against production tables) transmit query content to a third party without explicit informed consent. This may conflict with GDPR Article 28, HIPAA data-handling requirements, and SOC 2 data-classification obligations.Remediation**Option A (minimal) — redact known-sensitive argument values:****Option B (preferred) — transmit argument keys only, not values:****Option C — change to opt-in telemetry:**Set `usage_tracking_enabled` to `False` by default and require the user to set `DBT_SEND_ANONYMOUS_USAGE_STATS=true` to enable. Document this change prominently in the installation guide and README.
CVSS v3.1: 3.1