-
Notifications
You must be signed in to change notification settings - Fork 109
Description
Hi dbt team,
I've been building reachscan, a static analysis CLI for MCP servers, and ran it across 50 repos as part of a public audit. Here are the reachability findings for dbt-mcp.
Scanned: 103 files, 3 Python MCP entry points detected.
Reachable findings (12 total)
From dbt_compile (dbt_compile.py:18):
| Finding | File:Line | Capability | Reachability path |
|---|---|---|---|
subprocess.run() |
dbt_compile.py:34 | EXECUTE | dbt_compile → direct call |
dotenv.load_dotenv() |
(env setup) | SECRETS | dbt_compile → direct call |
os.getenv("DBT_PROJECT_LOCATION") |
(env setup) | SECRETS | dbt_compile → direct call |
os.getenv("DBT_EXECUTABLE") |
(env setup) | SECRETS | dbt_compile → direct call |
From dbt_model_analyzer_agent (dbt_model_analyzer.py:34):
| Finding | File:Line | Capability | Reachability path |
|---|---|---|---|
subprocess.run() |
dbt_model_analyzer.py:147 | EXECUTE | dbt_model_analyzer_agent → gather_dbt_project_info |
subprocess.run() |
dbt_model_analyzer.py:161 | EXECUTE | dbt_model_analyzer_agent → gather_dbt_project_info |
subprocess.run() |
dbt_model_analyzer.py:175 | EXECUTE | dbt_model_analyzer_agent → gather_dbt_project_info |
dotenv.load_dotenv() |
(env setup) | SECRETS | dbt_model_analyzer_agent → direct call |
os.getenv("DBT_PROJECT_LOCATION") |
(env setup) | SECRETS | dbt_model_analyzer_agent → direct call |
os.getenv("DBT_EXECUTABLE") |
(env setup) | SECRETS | dbt_model_analyzer_agent → direct call |
open(..., 'r') |
dbt_model_analyzer.py:135 | READ | dbt_model_analyzer_agent → gather_dbt_project_info |
48 additional findings are unreachable — buried in module-level code or utility paths not called from any MCP entry point.
Observations
-
DBT_EXECUTABLEsubprocess execution — thesubprocess.run()calls at dbt_model_analyzer.py:147/161/175 appear to invoke the dbt CLI binary. IfDBT_EXECUTABLEis configurable from env or the MCP call, an attacker with MCP access could point it at an arbitrary binary. Worth confirming the executable path is validated/pinned. -
Credential access scope —
dotenv.load_dotenv()loads whatever is in the.envfile at startup. The variables read (DBT_PROJECT_LOCATION,DBT_EXECUTABLE) look config-related rather than secret, but if the.envalso contains DB credentials or cloud keys, those are loaded into the process environment accessible to any LLM call. -
File reads —
open(..., 'r')at dbt_model_analyzer.py:135, called viagather_dbt_project_info, reads project files. Is the path parameter validated against the expected project directory?
These capabilities are expected for a dbt MCP integration — just flagging them so users can make an informed decision about their threat model before running this in an automated pipeline.
Full audit write-up and methodology: https://medium.com/@vinmayN/i-scanned-50-mcp-servers-to-see-what-they-can-actually-do-46144659ceca
Is any of this a false positive, or does the design already account for these paths? Happy to share the raw JSON scan output.