Skip to content
ATR-2026-01982mediumTool Poisoningdraft

dbt-mcp node_selection/resource_type Argument Injection (CVE-2026-44968)

Detects CVE-2026-44968 / GHSA-xpww-f6pm-cfhq (CWE-88): dbt-mcp's _run_dbt_command() in src/dbt_mcp/dbt_cli/tools.py appends the MCP-client-supplied node_selection string (split on space) and resource_type JSON array verbatim to the dbt subprocess argv without validating that tokens don't begin with a dash. Because Popen is called with shell=False, shell metacharacters are inert, but an attacker can still inject dbt global flags — --profiles-dir, --project-dir, --target, --profile — as independent argv elements on the build/compile/run/test/ clone/list/get_node_details_dev tools, redirecting dbt's configuration, project root, or execution target (demonstrated PoC: node_selection = "my_model --profiles-dir /tmp/evil" loads an attacker-controlled profiles.yml and writes to an attacker-chosen database path). Detection covers: (a) a node_selection value containing an injected dbt global flag token after the legitimate selector (space-separated, so the flag rides along as an extra "word"); (b) a resource_type JSON array containing an injected flag token as an array element instead of a valid resource type; (c) explicit CVE-2026-44968 / GHSA-xpww-f6pm-cfhq exploitation framing. The detection target is the request shape — a dash-prefixed dbt global flag riding inside a selector/resource-type value that should only ever contain a selector or resource-type token — which is the exact argument- injection primitive, caught before _run_dbt_command() extends argv. Bound to the dbt-mcp tool surface (node_selection/resource_type params) so a benign selector string elsewhere does not fire.

Severity
medium
Category
Tool Poisoning
Scan Target
mcp
Author
ATR Community

Response Actions

alertblock tool

References

OWASP Agentic
ASI06:2026 - Tool Misuse
OWASP LLM
LLM06:2025 - Excessive Agency
MITRE ATLAS
AML.T0053 - LLM Plugin Compromise

Detection Conditions

Combinator: any
  1. 01
    node_selection value whose space-separated tokens include an injected dbt global flag (--profiles-dir/--project-dir/--target/ --profile) after the legitimate selector — CVE-2026-44968 Vector 1.
    field: tool_argsop: regex
  2. 02
    resource_type JSON array containing an injected dbt global flag token as an array element instead of a valid resource type — CVE-2026-44968 Vector 2.
    field: tool_argsop: regex
  3. 03
    An injected dbt global flag pointing at an attacker-controlled path appearing alongside the vulnerable --select/--resource-type argv construction.
    field: tool_argsop: regex
  4. 04
    Explicit CVE-2026-44968 / GHSA-xpww-f6pm-cfhq reference combined with dbt-mcp argument-injection language — attack framing in a skill or tool description.
    field: contentop: regex

Attack Examples (Rule Triggers)

Real-world attack payloads, sanitized and versioned alongside the rule as regression tests — so a future revision can't silently stop catching them.

Benign Examples (Rule Doesn't Trigger)

  1. Legitimate dbt selector syntax with plus-operator and tag: method, no injected flag
  2. Valid resource_type array with only real dbt resource type names
  3. Benign question about dbt-mcp node_selection usage
  4. Simple model selector, no flags, read-only compile intent

Known False Positive Contexts

  • A node_selection value that legitimately contains a dbt selector method using a colon (tag:, config:) rather than a dash-prefixed flag.
  • Security advisory or PR text quoting the CVE-2026-44968 / GHSA-xpww-f6pm-cfhq payload for review purposes.
  • A resource_type array containing only valid dbt resource type names (model, test, snapshot, source, etc.) with no injected flag.

Full YAML Definition

Edit on GitHub →
title: "dbt-mcp node_selection/resource_type Argument Injection (CVE-2026-44968)"
id: ATR-2026-01982
rule_version: 1
status: draft
description: >
  Detects CVE-2026-44968 / GHSA-xpww-f6pm-cfhq (CWE-88): dbt-mcp's
  _run_dbt_command() in src/dbt_mcp/dbt_cli/tools.py appends the
  MCP-client-supplied node_selection string (split on space) and
  resource_type JSON array verbatim to the dbt subprocess argv without
  validating that tokens don't begin with a dash. Because Popen is called
  with shell=False, shell metacharacters are inert, but an attacker can still
  inject dbt global flags — --profiles-dir, --project-dir, --target,
  --profile — as independent argv elements on the build/compile/run/test/
  clone/list/get_node_details_dev tools, redirecting dbt's configuration,
  project root, or execution target (demonstrated PoC: node_selection =
  "my_model --profiles-dir /tmp/evil" loads an attacker-controlled
  profiles.yml and writes to an attacker-chosen database path).

  Detection covers:
  (a) a node_selection value containing an injected dbt global flag token
      after the legitimate selector (space-separated, so the flag rides
      along as an extra "word");
  (b) a resource_type JSON array containing an injected flag token as an
      array element instead of a valid resource type;
  (c) explicit CVE-2026-44968 / GHSA-xpww-f6pm-cfhq exploitation framing.

  The detection target is the request shape — a dash-prefixed dbt global
  flag riding inside a selector/resource-type value that should only ever
  contain a selector or resource-type token — which is the exact argument-
  injection primitive, caught before _run_dbt_command() extends argv. Bound
  to the dbt-mcp tool surface (node_selection/resource_type params) so a
  benign selector string elsewhere does not fire.
author: "ATR Community"
date: "2026/07/04"
schema_version: "0.1"
detection_tier: pattern
maturity: test
severity: medium

references:
  owasp_llm:
    - "LLM06:2025 - Excessive Agency"
  owasp_agentic:
    - "ASI06:2026 - Tool Misuse"
  mitre_atlas:
    - "AML.T0053 - LLM Plugin Compromise"
  mitre_attack:
    - "T1059 - Command and Scripting Interpreter"
  cve:
    - "CVE-2026-44968"
  ghsa:
    - "GHSA-xpww-f6pm-cfhq"

metadata_provenance:
  mitre_atlas: human-reviewed
  owasp_llm: human-reviewed
  owasp_agentic: human-reviewed

compliance:
  eu_ai_act:
    - { article: "15", context: "Article 15 cybersecurity — runtime detection of dbt-mcp node_selection/resource_type argument injection.", strength: primary }
    - { article: "9",  context: "Article 9 risk management — runtime risk-treatment control for dbt-mcp node_selection/resource_type argument injection.", strength: secondary }
  nist_ai_rmf:
    - { subcategory: "MP.5.1", context: "MAP 5.1 — adversarial input characterised/detected for dbt-mcp node_selection/resource_type argument injection.", strength: primary }
    - { subcategory: "MG.3.2", context: "MANAGE 3.2 — runtime monitoring control for dbt-mcp node_selection/resource_type argument injection.", strength: secondary }
  iso_42001:
    - { clause: "8.1", context: "Clause 8.1 operational control — detection of dbt-mcp node_selection/resource_type argument injection payload.", strength: primary }
    - { clause: "8.3", context: "Clause 8.3 AI risk treatment — runtime detection as treatment control.", strength: secondary }

tags:
  category: tool-poisoning
  subcategory: argument-injection
  scan_target: mcp
  confidence: high
  source: cve-disclosure
  vendor_sources: dbt-mcp-cve-2026-44968

agent_source:
  type: tool_call
  framework:
    - dbt-mcp
    - any
  provider:
    - any

detection:
  condition: any
  false_positives:
    - "A node_selection value that legitimately contains a dbt selector method using a colon (tag:, config:) rather than a dash-prefixed flag."
    - "Security advisory or PR text quoting the CVE-2026-44968 / GHSA-xpww-f6pm-cfhq payload for review purposes."
    - "A resource_type array containing only valid dbt resource type names (model, test, snapshot, source, etc.) with no injected flag."
  conditions:
    - field: tool_args
      operator: regex
      value: '(?i)\bnode_selection["\x27]?\s*[:=]\s*["\x27][^"\x27\n]{0,200}\s(?:--profiles-dir|--project-dir|--target|--profile)\b'
      description: >
        node_selection value whose space-separated tokens include an
        injected dbt global flag (--profiles-dir/--project-dir/--target/
        --profile) after the legitimate selector — CVE-2026-44968 Vector 1.
    - field: tool_args
      operator: regex
      value: '(?i)\bresource_type["\x27]?\s*[:=]\s*\[[^\]\n]{0,200}["\x27](?:--profiles-dir|--project-dir|--target|--profile)["\x27][^\]\n]{0,200}\]'
      description: >
        resource_type JSON array containing an injected dbt global flag
        token as an array element instead of a valid resource type —
        CVE-2026-44968 Vector 2.
    - field: tool_args
      operator: regex
      value: '(?i)--(?:profiles-dir|project-dir|target|profile)\s+["\x27]?/tmp/[^"\x27\s\n]{0,80}["\x27]?[\s\S]{0,120}\b(?:node_selection|resource_type|--select|--resource-type)\b'
      description: >
        An injected dbt global flag pointing at an attacker-controlled path
        appearing alongside the vulnerable --select/--resource-type argv
        construction.
    - field: content
      operator: regex
      value: '(?i)(?:CVE-2026-44968|GHSA-xpww-f6pm-cfhq)[\s\S]{0,200}(?:dbt-mcp|node_selection|resource_type|profiles-dir|argument\s*inject)'
      description: >
        Explicit CVE-2026-44968 / GHSA-xpww-f6pm-cfhq reference combined with
        dbt-mcp argument-injection language — attack framing in a skill or
        tool description.

response:
  actions:
    - alert
    - block_tool
  message_template: >
    [ATR-2026-01982] MEDIUM: dbt-mcp node_selection/resource_type argument
    injection detected (CVE-2026-44968, CWE-88). A tool argument injects a
    dbt global flag (--profiles-dir/--project-dir/--target) as an argv
    element; dbt-mcp before 1.17.1 appends this to the dbt subprocess
    unsanitized. Block the tool call and upgrade dbt-mcp to >= 1.17.1.

confidence: 80

wild_fp_rate: 0

test_cases:
  true_positives:
    - tool_args: 'node_selection="my_first_model --profiles-dir /tmp/evil-profiles"'
      expected: triggered
      description: "PoC Vector 1: node_selection injects --profiles-dir pointing at attacker path"
    - tool_args: 'resource_type=["model", "--profiles-dir", "/tmp/evil-profiles"]'
      expected: triggered
      description: "PoC Vector 2: resource_type array smuggles --profiles-dir as an element"
    - tool_description: "Exploiting CVE-2026-44968 (GHSA-xpww-f6pm-cfhq) in dbt-mcp: craft node_selection to inject --profiles-dir for argument injection against the dbt CLI."
      expected: triggered
      description: "Explicit CVE-2026-44968 dbt-mcp exploitation framing"
  true_negatives:
    - tool_args: 'node_selection="my_first_model+ tag:nightly"'
      expected: not_triggered
      description: "Legitimate dbt selector syntax with plus-operator and tag: method, no injected flag"
    - tool_args: 'resource_type=["model", "test", "source"]'
      expected: not_triggered
      description: "Valid resource_type array with only real dbt resource type names"
    - content: "How do I filter dbt models using node_selection in the dbt-mcp run tool?"
      expected: not_triggered
      description: "Benign question about dbt-mcp node_selection usage"
    - tool_args: 'node_selection="staging.orders"'
      expected: not_triggered
      description: "Simple model selector, no flags, read-only compile intent"

Revision History

Created
2026-07-04
Last modified
2026-07-05
View full commit history on GitHub →