agent-threat-rules 3.5.4 → 3.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/README.md +1 -1
  2. package/dist/engine.d.ts +17 -0
  3. package/dist/engine.d.ts.map +1 -1
  4. package/dist/engine.js +127 -53
  5. package/dist/engine.js.map +1 -1
  6. package/dist/hook-handler.d.ts +25 -1
  7. package/dist/hook-handler.d.ts.map +1 -1
  8. package/dist/hook-handler.js +64 -2
  9. package/dist/hook-handler.js.map +1 -1
  10. package/package.json +2 -2
  11. package/rules/context-exfiltration/ATR-2026-01984-mcp-server-kubernetes-kubectl-generic-token-exfil.yaml +170 -0
  12. package/rules/privilege-escalation/ATR-2026-00111-shell-escape.yaml +19 -11
  13. package/rules/privilege-escalation/ATR-2026-01933-litellm-user-role-privilege-escalation-cve-2026-47102.yaml +160 -0
  14. package/rules/privilege-escalation/ATR-2026-01934-litellm-allowed-routes-authz-bypass-cve-2026-47101.yaml +161 -0
  15. package/rules/privilege-escalation/ATR-2026-01981-network-ai-approval-inbox-unauth-cors-bypass.yaml +152 -0
  16. package/rules/privilege-escalation/ATR-2026-01986-windows-mcp-unauth-http-powershell-cors.yaml +170 -0
  17. package/rules/skill-compromise/ATR-2026-00066-parameter-injection.yaml +2 -2
  18. package/rules/tool-poisoning/ATR-2026-00012-unauthorized-tool-call.yaml +3 -3
  19. package/rules/tool-poisoning/ATR-2026-00161-important-tag-cross-tool-shadowing.yaml +4 -3
  20. package/rules/tool-poisoning/ATR-2026-00581-mcp-tool-rug-pull-post-approval-redefinition.yaml +1 -0
  21. package/rules/tool-poisoning/ATR-2026-01932-shadow-undeclared-mcp-server-registration.yaml +1 -0
  22. package/rules/tool-poisoning/ATR-2026-01935-litellm-custom-code-sandbox-escape-cve-2026-40217.yaml +161 -0
  23. package/rules/tool-poisoning/ATR-2026-01980-agentic-flow-mcp-tool-param-command-injection.yaml +153 -0
  24. package/rules/tool-poisoning/ATR-2026-01982-dbt-mcp-node-selection-argument-injection.yaml +160 -0
  25. package/rules/tool-poisoning/ATR-2026-01983-mcp-for-stata-log-file-name-command-injection.yaml +170 -0
  26. package/rules/tool-poisoning/ATR-2026-01985-mcp-connect-bridge-unauth-process-spawn-rce.yaml +180 -0
  27. package/rules/tool-poisoning/ATR-2026-01987-langroid-sqlchatagent-prompt-to-sql-rce.yaml +165 -0
@@ -0,0 +1,161 @@
1
+ title: "LiteLLM Custom-Code Guardrail Sandbox Escape (CVE-2026-40217)"
2
+ id: ATR-2026-01935
3
+ rule_version: 1
4
+ status: draft
5
+ description: >
6
+ Detects CVE-2026-40217 (CWE-94/CWE-265): LiteLLM's custom-code guardrail
7
+ test/compile path /guardrails/test_custom_code evaluates caller-supplied
8
+ Python in an unsafe sandbox that can be escaped via bytecode rewriting and
9
+ dunder-attribute traversal, yielding server-side code execution as the
10
+ LiteLLM proxy process. Affected through 2026-04-08 builds.
11
+
12
+ Detection covers:
13
+ (a) a request to the /guardrails/test_custom_code endpoint carrying Python
14
+ code-execution primitives (import os, subprocess, exec/eval/compile);
15
+ (b) sandbox-escape primitives (dunder traversal __subclasses__/__globals__/
16
+ __builtins__, code-object/bytecode rewriting) in a guardrail code body;
17
+ (c) explicit CVE-2026-40217 exploitation framing.
18
+
19
+ The detection target is custom guardrail code reaching the test endpoint
20
+ with escape primitives — the exact sandbox-escape shape — caught before the
21
+ proxy compiles and runs it.
22
+ author: "ATR Community"
23
+ date: "2026/06/26"
24
+ schema_version: "0.1"
25
+ detection_tier: pattern
26
+ maturity: test
27
+ severity: critical
28
+
29
+ references:
30
+ owasp_llm:
31
+ - "LLM05:2025 - Improper Output Handling"
32
+ - "LLM06:2025 - Excessive Agency"
33
+ owasp_agentic:
34
+ - "ASI05:2026 - Unexpected Code Execution"
35
+ - "ASI06:2026 - Tool Misuse"
36
+ mitre_atlas:
37
+ - "AML.T0049 - Exploit Public-Facing Application"
38
+ mitre_attack:
39
+ - "T1059.006 - Command and Scripting Interpreter: Python"
40
+ cve:
41
+ - "CVE-2026-40217"
42
+
43
+ metadata_provenance:
44
+ mitre_atlas: human-reviewed
45
+ owasp_llm: human-reviewed
46
+ owasp_agentic: human-reviewed
47
+
48
+ compliance:
49
+ eu_ai_act:
50
+ - article: "15"
51
+ context: >
52
+ CVE-2026-40217 lets a caller escape the LiteLLM custom-code guardrail
53
+ sandbox and run code as the proxy; Article 15 cybersecurity
54
+ requirements mandate that AI guardrail code-evaluation paths refuse
55
+ sandbox-escape primitives.
56
+ strength: primary
57
+ - article: "9"
58
+ context: "Article 9 (risk management system) requires identified risks to be addressed by appropriate measures; this rule is a runtime risk-treatment control that detects the code-execution technique (LiteLLM Custom-Code Guardrail Sandbox Escape (CVE-2026-40217))."
59
+ strength: secondary
60
+ nist_ai_rmf:
61
+ - subcategory: "MP.5.1"
62
+ context: >
63
+ Custom guardrail code carrying sandbox-escape primitives is an
64
+ adversarial input; MP.5.1 requires scanning /guardrails/test_custom_code
65
+ payloads for code-execution and dunder-traversal patterns.
66
+ strength: primary
67
+ - subcategory: "MG.3.2"
68
+ context: "NIST AI RMF MANAGE 3.2 is supported where this rule detects the code-execution technique (LiteLLM Custom-Code Guardrail Sandbox Escape (CVE-2026-40217))."
69
+ strength: secondary
70
+ iso_42001:
71
+ - clause: "8.1"
72
+ context: >
73
+ Operational controls must detect guardrail code-evaluation payloads
74
+ carrying sandbox-escape primitives at the LiteLLM test endpoint before
75
+ the proxy compiles and runs them.
76
+ strength: primary
77
+ - clause: "8.3"
78
+ context: "ISO/IEC 42001 Clause 8.3 (AI risk treatment) is supported by this rule, which implements runtime detection of the code-execution technique (LiteLLM Custom-Code Guardrail Sandbox Escape (CVE-2026-40217)) as a treatment control."
79
+ strength: secondary
80
+
81
+ tags:
82
+ category: tool-poisoning
83
+ subcategory: sandbox-escape
84
+ scan_target: both
85
+ confidence: high
86
+ source: cve-disclosure
87
+ vendor_sources: litellm-cve-2026-40217
88
+
89
+ agent_source:
90
+ type: llm_io
91
+ framework:
92
+ - litellm
93
+ - any
94
+ provider:
95
+ - any
96
+
97
+ detection:
98
+ condition: any
99
+ false_positives:
100
+ - "Security advisory or PR text quoting the CVE-2026-40217 sandbox-escape payload."
101
+ - "A benign custom guardrail that only inspects request text and uses no os/subprocess/exec or dunder traversal."
102
+ - "Documentation describing the /guardrails endpoints without code-execution primitives."
103
+ conditions:
104
+ - field: content
105
+ operator: regex
106
+ value: '(?i)/guardrails/test_custom_code[\s\S]{0,400}(?:import\s+os\b|import\s+subprocess\b|subprocess\.(?:Popen|run|call|check_output)|\bos\.(?:system|popen|exec|spawn)|\bexec\s*\(|\beval\s*\(|\bcompile\s*\()'
107
+ description: >
108
+ A request to /guardrails/test_custom_code carrying Python
109
+ code-execution primitives — direct CVE-2026-40217 attack shape.
110
+ - field: content
111
+ operator: regex
112
+ value: '(?i)(?:test_custom_code|custom[_-]?code[_-]?guardrail)[\s\S]{0,400}(?:__subclasses__|__globals__|__builtins__|__class__\s*\.\s*__|\bco_code\b|types\.CodeType|\.__code__\b|bytecode)'
113
+ description: >
114
+ Custom guardrail code reaching the test path with dunder-traversal or
115
+ bytecode-rewriting sandbox-escape primitives.
116
+ - field: content
117
+ operator: regex
118
+ value: '(?i)CVE-2026-40217[\s\S]{0,200}(?:litellm|guardrail|sandbox|custom[_\s-]?code|bytecode|escape|rce)'
119
+ description: >
120
+ Explicit CVE-2026-40217 reference combined with LiteLLM guardrail
121
+ sandbox-escape language — attack framing in a skill or tool description.
122
+
123
+ response:
124
+ actions:
125
+ - alert
126
+ - block_input
127
+ message_template: >
128
+ [ATR-2026-01935] CRITICAL: LiteLLM custom-code guardrail sandbox escape
129
+ detected (CVE-2026-40217, CWE-94). Custom guardrail code reaches
130
+ /guardrails/test_custom_code with code-execution or sandbox-escape
131
+ primitives, yielding RCE as the proxy. Block the request and upgrade
132
+ LiteLLM to a build after 2026-04-08.
133
+
134
+ confidence: 80
135
+
136
+ wild_fp_rate: 0
137
+
138
+ test_cases:
139
+ true_positives:
140
+ - input: "POST /guardrails/test_custom_code {\"code\": \"import os; os.system('id')\"}"
141
+ expected: triggered
142
+ description: "Custom-code guardrail test payload running os.system"
143
+ - input: "POST /guardrails/test_custom_code {\"code\": \"().__class__.__bases__[0].__subclasses__()\"}"
144
+ expected: triggered
145
+ description: "Dunder-traversal sandbox escape via test_custom_code"
146
+ - input: "CVE-2026-40217: send custom_code guardrail to LiteLLM /guardrails/test_custom_code using bytecode rewriting to escape the sandbox for RCE."
147
+ expected: triggered
148
+ description: "Explicit CVE-2026-40217 LiteLLM sandbox-escape framing"
149
+ true_negatives:
150
+ - input: "POST /guardrails/test_custom_code {\"code\": \"return 'blocked' if 'ssn' in text else 'allow'\"}"
151
+ expected: not_triggered
152
+ description: "Benign guardrail inspecting text, no os/exec/dunder primitives"
153
+ - input: "GET /guardrails/list"
154
+ expected: not_triggered
155
+ description: "Read-only guardrail listing, no custom code"
156
+ - input: "How do custom-code guardrails work in LiteLLM?"
157
+ expected: not_triggered
158
+ description: "General question, no code-execution primitives"
159
+ - input: "import os is a common Python pattern in many legitimate scripts."
160
+ expected: not_triggered
161
+ description: "import os outside the test_custom_code endpoint context"
@@ -0,0 +1,153 @@
1
+ title: "Agentic-Flow MCP Tool-Parameter OS Command Injection (GHSA-vcv2-r9jh-99m5)"
2
+ id: ATR-2026-01980
3
+ rule_version: 1
4
+ status: draft
5
+ description: >
6
+ Detects GHSA-vcv2-r9jh-99m5 (CWE-78): agentic-flow <= 2.0.13 MCP server
7
+ tools (agentic_flow_agent, agentic_flow_create_agent, agent_booster_edit_file,
8
+ agentdb_pattern_store, and related tools under standalone-stdio.ts / fastmcp
9
+ servers) interpolate attacker-influenceable parameters (agent, task, name,
10
+ language, agentdb arguments) directly into shell strings passed to
11
+ execSync(). A parameter value that breaks out of the surrounding
12
+ double-quoted argument executes arbitrary OS commands with the privileges
13
+ of the MCP server process.
14
+
15
+ Detection covers:
16
+ (a) an agentic-flow tool-call argument value containing a double-quote
17
+ breakout followed by shell command chaining (`; `, backticks, or
18
+ `$(...)`) — the exact PoC shape from the advisory
19
+ (task = `x"; touch /tmp/INJECTED; id > /tmp/rce.txt; echo "`);
20
+ (b) the resulting interpolated `npx ... agentic-flow --agent/--task`
21
+ command string itself carrying injected shell metacharacters;
22
+ (c) explicit GHSA-vcv2-r9jh-99m5 exploitation framing.
23
+
24
+ The detection target is the request shape — a quote-breakout + command
25
+ chain inside an agentic-flow tool argument — which is the exact
26
+ command-injection primitive, caught before execSync() hands it to
27
+ /bin/sh -c. Bound to the agentic-flow tool surface so a benign
28
+ shell-looking string elsewhere does not fire.
29
+ author: "ATR Community"
30
+ date: "2026/07/04"
31
+ schema_version: "0.1"
32
+ detection_tier: pattern
33
+ maturity: test
34
+ severity: critical
35
+
36
+ references:
37
+ owasp_llm:
38
+ - "LLM06:2025 - Excessive Agency"
39
+ owasp_agentic:
40
+ - "ASI06:2026 - Tool Misuse"
41
+ mitre_atlas:
42
+ - "AML.T0053 - LLM Plugin Compromise"
43
+ mitre_attack:
44
+ - "T1059 - Command and Scripting Interpreter"
45
+ ghsa:
46
+ - "GHSA-vcv2-r9jh-99m5"
47
+
48
+ metadata_provenance:
49
+ mitre_atlas: human-reviewed
50
+ owasp_llm: human-reviewed
51
+ owasp_agentic: human-reviewed
52
+
53
+ compliance:
54
+ eu_ai_act:
55
+ - { article: "15", context: "Article 15 cybersecurity — runtime detection of agentic-flow MCP tool-parameter OS command injection.", strength: primary }
56
+ - { article: "9", context: "Article 9 risk management — runtime risk-treatment control for agentic-flow MCP tool-parameter OS command injection.", strength: secondary }
57
+ nist_ai_rmf:
58
+ - { subcategory: "MP.5.1", context: "MAP 5.1 — adversarial input characterised/detected for agentic-flow MCP tool-parameter OS command injection.", strength: primary }
59
+ - { subcategory: "MG.3.2", context: "MANAGE 3.2 — runtime monitoring control for agentic-flow MCP tool-parameter OS command injection.", strength: secondary }
60
+ iso_42001:
61
+ - { clause: "8.1", context: "Clause 8.1 operational control — detection of agentic-flow MCP tool-parameter OS command injection payload.", strength: primary }
62
+ - { clause: "8.3", context: "Clause 8.3 AI risk treatment — runtime detection as treatment control.", strength: secondary }
63
+
64
+ tags:
65
+ category: tool-poisoning
66
+ subcategory: command-injection
67
+ scan_target: mcp
68
+ confidence: high
69
+ source: ghsa-disclosure
70
+ vendor_sources: agentic-flow-ghsa-vcv2-r9jh-99m5
71
+
72
+ agent_source:
73
+ type: tool_call
74
+ framework:
75
+ - agentic-flow
76
+ - any
77
+ provider:
78
+ - any
79
+
80
+ detection:
81
+ condition: any
82
+ false_positives:
83
+ - "A tool_args value that legitimately contains a semicolon or backtick as literal text data (e.g. discussing shell syntax) without an adjacent quote-breakout shape."
84
+ - "Security advisory or PR text quoting the GHSA-vcv2-r9jh-99m5 payload for review purposes."
85
+ - "A benign agentic-flow agent/task value with no quote character or shell metacharacter."
86
+ conditions:
87
+ - field: tool_args
88
+ operator: regex
89
+ value: '(?i)\b(?:agent|task|name|language|agentdb)["\x27]?\s*[:=]\s*["\x27][^"\x27\n]{0,200}["\x27]\s*;\s*[\s\S]{0,120}\b(?:touch|rm|curl|wget|cat|id|nc|bash|sh|chmod|echo)\b'
90
+ description: >
91
+ agentic-flow tool argument (agent/task/name/language/agentdb) whose
92
+ value breaks out of its quote with `";` followed by a chained shell
93
+ command — the canonical GHSA-vcv2-r9jh-99m5 PoC shape.
94
+ - field: tool_args
95
+ operator: regex
96
+ value: '(?i)npx\s+--yes\s+agentic-flow[\s\S]{0,80}--(?:agent|task)\s+"[^"\n]{0,200}"\s*;\s*[\s\S]{0,120}\b(?:touch|rm|curl|wget|cat|id|nc|bash|sh|chmod)\b'
97
+ description: >
98
+ The interpolated `npx --yes agentic-flow --agent/--task` command
99
+ string itself carrying an injected chained shell command after the
100
+ closing quote — the post-interpolation execSync() payload.
101
+ - field: tool_args
102
+ operator: regex
103
+ value: '(?i)["\x27][^"\x27\n]{0,200}["\x27]\s*;[\s\S]{0,80}`[^`\n]{0,120}`|["\x27][^"\x27\n]{0,200}["\x27]\s*;[\s\S]{0,80}\$\([^)\n]{0,120}\)'
104
+ description: >
105
+ Quote-breakout followed by a backtick or $() command substitution
106
+ inside an agentic-flow tool argument.
107
+ - field: content
108
+ operator: regex
109
+ value: '(?i)GHSA-vcv2-r9jh-99m5[\s\S]{0,200}(?:agentic-flow|execSync|command\s*inject|RCE)'
110
+ description: >
111
+ Explicit GHSA-vcv2-r9jh-99m5 reference combined with agentic-flow
112
+ command-injection language — attack framing in a skill or tool
113
+ description.
114
+
115
+ response:
116
+ actions:
117
+ - alert
118
+ - block_tool
119
+ message_template: >
120
+ [ATR-2026-01980] CRITICAL: Agentic-Flow MCP tool-parameter OS command
121
+ injection detected (GHSA-vcv2-r9jh-99m5, CWE-78). A tool argument breaks
122
+ out of its shell quote and chains a command; agentic-flow <= 2.0.13
123
+ interpolates this into execSync() unsanitized. Block the tool call and
124
+ upgrade agentic-flow to >= 2.0.14.
125
+
126
+ confidence: 85
127
+
128
+ wild_fp_rate: 0
129
+
130
+ test_cases:
131
+ true_positives:
132
+ - tool_args: 'task="x\"; touch /tmp/INJECTED; id > /tmp/rce.txt; echo \""'
133
+ expected: triggered
134
+ description: "Canonical PoC: task param quote-breakout chaining touch+id+echo"
135
+ - tool_args: 'npx --yes agentic-flow --agent "coder" --task "x"; touch /tmp/INJECTED; id > /tmp/rce.txt; echo ""'
136
+ expected: triggered
137
+ description: "Post-interpolation execSync() command string with injected chain"
138
+ - tool_description: "Exploiting GHSA-vcv2-r9jh-99m5 in agentic-flow: craft a task value that breaks the execSync quoting for command injection RCE."
139
+ expected: triggered
140
+ description: "Explicit GHSA-vcv2-r9jh-99m5 agentic-flow exploitation framing"
141
+ true_negatives:
142
+ - tool_args: 'agent="coder", task="Refactor the login handler to use async/await"'
143
+ expected: not_triggered
144
+ description: "Legitimate agentic-flow task description, no quote-breakout"
145
+ - content: "How do I configure the agentic-flow MCP server's agent and task parameters?"
146
+ expected: not_triggered
147
+ description: "Benign question about agentic-flow configuration"
148
+ - tool_args: 'name="release-notes", language="typescript"'
149
+ expected: not_triggered
150
+ description: "Normal name/language params with no shell metacharacters"
151
+ - tool_args: 'agentdb_pattern_search query="find all functions that touch the user; audit them"'
152
+ expected: not_triggered
153
+ description: "Benign text containing the word touch and a semicolon in natural language, no quote-breakout or dangerous command token"
@@ -0,0 +1,160 @@
1
+ title: "dbt-mcp node_selection/resource_type Argument Injection (CVE-2026-44968)"
2
+ id: ATR-2026-01982
3
+ rule_version: 1
4
+ status: draft
5
+ description: >
6
+ Detects CVE-2026-44968 / GHSA-xpww-f6pm-cfhq (CWE-88): dbt-mcp's
7
+ _run_dbt_command() in src/dbt_mcp/dbt_cli/tools.py appends the
8
+ MCP-client-supplied node_selection string (split on space) and
9
+ resource_type JSON array verbatim to the dbt subprocess argv without
10
+ validating that tokens don't begin with a dash. Because Popen is called
11
+ with shell=False, shell metacharacters are inert, but an attacker can still
12
+ inject dbt global flags — --profiles-dir, --project-dir, --target,
13
+ --profile — as independent argv elements on the build/compile/run/test/
14
+ clone/list/get_node_details_dev tools, redirecting dbt's configuration,
15
+ project root, or execution target (demonstrated PoC: node_selection =
16
+ "my_model --profiles-dir /tmp/evil" loads an attacker-controlled
17
+ profiles.yml and writes to an attacker-chosen database path).
18
+
19
+ Detection covers:
20
+ (a) a node_selection value containing an injected dbt global flag token
21
+ after the legitimate selector (space-separated, so the flag rides
22
+ along as an extra "word");
23
+ (b) a resource_type JSON array containing an injected flag token as an
24
+ array element instead of a valid resource type;
25
+ (c) explicit CVE-2026-44968 / GHSA-xpww-f6pm-cfhq exploitation framing.
26
+
27
+ The detection target is the request shape — a dash-prefixed dbt global
28
+ flag riding inside a selector/resource-type value that should only ever
29
+ contain a selector or resource-type token — which is the exact argument-
30
+ injection primitive, caught before _run_dbt_command() extends argv. Bound
31
+ to the dbt-mcp tool surface (node_selection/resource_type params) so a
32
+ benign selector string elsewhere does not fire.
33
+ author: "ATR Community"
34
+ date: "2026/07/04"
35
+ schema_version: "0.1"
36
+ detection_tier: pattern
37
+ maturity: test
38
+ severity: medium
39
+
40
+ references:
41
+ owasp_llm:
42
+ - "LLM06:2025 - Excessive Agency"
43
+ owasp_agentic:
44
+ - "ASI06:2026 - Tool Misuse"
45
+ mitre_atlas:
46
+ - "AML.T0053 - LLM Plugin Compromise"
47
+ mitre_attack:
48
+ - "T1059 - Command and Scripting Interpreter"
49
+ cve:
50
+ - "CVE-2026-44968"
51
+ ghsa:
52
+ - "GHSA-xpww-f6pm-cfhq"
53
+
54
+ metadata_provenance:
55
+ mitre_atlas: human-reviewed
56
+ owasp_llm: human-reviewed
57
+ owasp_agentic: human-reviewed
58
+
59
+ compliance:
60
+ eu_ai_act:
61
+ - { article: "15", context: "Article 15 cybersecurity — runtime detection of dbt-mcp node_selection/resource_type argument injection.", strength: primary }
62
+ - { article: "9", context: "Article 9 risk management — runtime risk-treatment control for dbt-mcp node_selection/resource_type argument injection.", strength: secondary }
63
+ nist_ai_rmf:
64
+ - { subcategory: "MP.5.1", context: "MAP 5.1 — adversarial input characterised/detected for dbt-mcp node_selection/resource_type argument injection.", strength: primary }
65
+ - { subcategory: "MG.3.2", context: "MANAGE 3.2 — runtime monitoring control for dbt-mcp node_selection/resource_type argument injection.", strength: secondary }
66
+ iso_42001:
67
+ - { clause: "8.1", context: "Clause 8.1 operational control — detection of dbt-mcp node_selection/resource_type argument injection payload.", strength: primary }
68
+ - { clause: "8.3", context: "Clause 8.3 AI risk treatment — runtime detection as treatment control.", strength: secondary }
69
+
70
+ tags:
71
+ category: tool-poisoning
72
+ subcategory: argument-injection
73
+ scan_target: mcp
74
+ confidence: high
75
+ source: cve-disclosure
76
+ vendor_sources: dbt-mcp-cve-2026-44968
77
+
78
+ agent_source:
79
+ type: tool_call
80
+ framework:
81
+ - dbt-mcp
82
+ - any
83
+ provider:
84
+ - any
85
+
86
+ detection:
87
+ condition: any
88
+ false_positives:
89
+ - "A node_selection value that legitimately contains a dbt selector method using a colon (tag:, config:) rather than a dash-prefixed flag."
90
+ - "Security advisory or PR text quoting the CVE-2026-44968 / GHSA-xpww-f6pm-cfhq payload for review purposes."
91
+ - "A resource_type array containing only valid dbt resource type names (model, test, snapshot, source, etc.) with no injected flag."
92
+ conditions:
93
+ - field: tool_args
94
+ operator: regex
95
+ value: '(?i)\bnode_selection["\x27]?\s*[:=]\s*["\x27][^"\x27\n]{0,200}\s(?:--profiles-dir|--project-dir|--target|--profile)\b'
96
+ description: >
97
+ node_selection value whose space-separated tokens include an
98
+ injected dbt global flag (--profiles-dir/--project-dir/--target/
99
+ --profile) after the legitimate selector — CVE-2026-44968 Vector 1.
100
+ - field: tool_args
101
+ operator: regex
102
+ value: '(?i)\bresource_type["\x27]?\s*[:=]\s*\[[^\]\n]{0,200}["\x27](?:--profiles-dir|--project-dir|--target|--profile)["\x27][^\]\n]{0,200}\]'
103
+ description: >
104
+ resource_type JSON array containing an injected dbt global flag
105
+ token as an array element instead of a valid resource type —
106
+ CVE-2026-44968 Vector 2.
107
+ - field: tool_args
108
+ operator: regex
109
+ 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'
110
+ description: >
111
+ An injected dbt global flag pointing at an attacker-controlled path
112
+ appearing alongside the vulnerable --select/--resource-type argv
113
+ construction.
114
+ - field: content
115
+ operator: regex
116
+ value: '(?i)(?:CVE-2026-44968|GHSA-xpww-f6pm-cfhq)[\s\S]{0,200}(?:dbt-mcp|node_selection|resource_type|profiles-dir|argument\s*inject)'
117
+ description: >
118
+ Explicit CVE-2026-44968 / GHSA-xpww-f6pm-cfhq reference combined with
119
+ dbt-mcp argument-injection language — attack framing in a skill or
120
+ tool description.
121
+
122
+ response:
123
+ actions:
124
+ - alert
125
+ - block_tool
126
+ message_template: >
127
+ [ATR-2026-01982] MEDIUM: dbt-mcp node_selection/resource_type argument
128
+ injection detected (CVE-2026-44968, CWE-88). A tool argument injects a
129
+ dbt global flag (--profiles-dir/--project-dir/--target) as an argv
130
+ element; dbt-mcp before 1.17.1 appends this to the dbt subprocess
131
+ unsanitized. Block the tool call and upgrade dbt-mcp to >= 1.17.1.
132
+
133
+ confidence: 80
134
+
135
+ wild_fp_rate: 0
136
+
137
+ test_cases:
138
+ true_positives:
139
+ - tool_args: 'node_selection="my_first_model --profiles-dir /tmp/evil-profiles"'
140
+ expected: triggered
141
+ description: "PoC Vector 1: node_selection injects --profiles-dir pointing at attacker path"
142
+ - tool_args: 'resource_type=["model", "--profiles-dir", "/tmp/evil-profiles"]'
143
+ expected: triggered
144
+ description: "PoC Vector 2: resource_type array smuggles --profiles-dir as an element"
145
+ - 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."
146
+ expected: triggered
147
+ description: "Explicit CVE-2026-44968 dbt-mcp exploitation framing"
148
+ true_negatives:
149
+ - tool_args: 'node_selection="my_first_model+ tag:nightly"'
150
+ expected: not_triggered
151
+ description: "Legitimate dbt selector syntax with plus-operator and tag: method, no injected flag"
152
+ - tool_args: 'resource_type=["model", "test", "source"]'
153
+ expected: not_triggered
154
+ description: "Valid resource_type array with only real dbt resource type names"
155
+ - content: "How do I filter dbt models using node_selection in the dbt-mcp run tool?"
156
+ expected: not_triggered
157
+ description: "Benign question about dbt-mcp node_selection usage"
158
+ - tool_args: 'node_selection="staging.orders"'
159
+ expected: not_triggered
160
+ description: "Simple model selector, no flags, read-only compile intent"
@@ -0,0 +1,170 @@
1
+ title: "MCP-for-Stata: Command Injection via log_file_name Parameter (CVE-2026-47708)"
2
+ id: ATR-2026-01983
3
+ rule_version: 1
4
+ status: draft
5
+ description: >
6
+ Detects CVE-2026-47708 (CVSS critical, CWE-77): the `log_file_name` (aka
7
+ `log_name`) parameter accepted by the `stata_do` MCP tool / CLI is
8
+ interpolated directly into a Stata `log using "<log_file>", ...` command
9
+ string without sanitization. GuardValidator only scans do-file content, not
10
+ this wrapper parameter. An attacker breaks out of the quoted log-path
11
+ string with a quote or newline and appends a dangerous Stata command
12
+ (`shell`, `python`, `erase`, `winexec`, or `!` shell-escape), achieving
13
+ remote code execution, or supplies `../` path-traversal segments in
14
+ log_name to write arbitrary files outside the log directory.
15
+
16
+ Detection covers:
17
+ (a) a stata_do tool call whose log_file_name/log_name value contains a
18
+ quote/newline breakout followed by a dangerous Stata command token;
19
+ (b) a log_file_name/log_name value containing path-traversal segments;
20
+ (c) explicit CVE-2026-47708 exploitation framing referencing the
21
+ log_file_name / stata_do injection.
22
+
23
+ The detection target is the request shape — a stata_do log_file_name
24
+ parameter carrying a string-breakout plus command injection or path
25
+ traversal — the exact CVE-2026-47708 primitive, caught before the
26
+ wrapper builds the Stata command string.
27
+ author: "ATR Community"
28
+ date: "2026/07/04"
29
+ schema_version: "0.1"
30
+ detection_tier: pattern
31
+ maturity: test
32
+ severity: critical
33
+
34
+ references:
35
+ owasp_llm:
36
+ - "LLM06:2025 - Excessive Agency"
37
+ owasp_agentic:
38
+ - "ASI06:2026 - Tool Misuse"
39
+ mitre_atlas:
40
+ - "AML.T0053 - LLM Plugin Compromise"
41
+ mitre_attack:
42
+ - "T1059 - Command and Scripting Interpreter"
43
+ cve:
44
+ - "CVE-2026-47708"
45
+
46
+ metadata_provenance:
47
+ mitre_atlas: human-reviewed
48
+ owasp_llm: human-reviewed
49
+ owasp_agentic: human-reviewed
50
+
51
+ compliance:
52
+ eu_ai_act:
53
+ - article: "15"
54
+ context: "Article 15 cybersecurity — runtime detection of MCP-for-Stata log_file_name command injection (CVE-2026-47708)."
55
+ strength: primary
56
+ - article: "9"
57
+ context: "Article 9 risk management — runtime risk-treatment control for MCP-for-Stata log_file_name command injection (CVE-2026-47708)."
58
+ strength: secondary
59
+ nist_ai_rmf:
60
+ - subcategory: "MP.5.1"
61
+ context: "MAP 5.1 — adversarial input characterised/detected for MCP-for-Stata log_file_name command injection (CVE-2026-47708)."
62
+ strength: primary
63
+ - subcategory: "MG.3.2"
64
+ context: "MANAGE 3.2 — runtime monitoring control for MCP-for-Stata log_file_name command injection (CVE-2026-47708)."
65
+ strength: secondary
66
+ iso_42001:
67
+ - clause: "8.1"
68
+ context: "Clause 8.1 operational control — detection of MCP-for-Stata log_file_name command injection payload."
69
+ strength: primary
70
+ - clause: "8.3"
71
+ context: "Clause 8.3 AI risk treatment — runtime detection as treatment control."
72
+ strength: secondary
73
+
74
+ tags:
75
+ category: tool-poisoning
76
+ subcategory: mcp-command-injection
77
+ scan_target: runtime
78
+ confidence: high
79
+ source: cve-disclosure
80
+ vendor_sources: mcp-for-stata-cve-2026-47708
81
+
82
+ agent_source:
83
+ type: tool_call
84
+ framework:
85
+ - any
86
+ provider:
87
+ - any
88
+
89
+ detection:
90
+ condition: any
91
+ false_positives:
92
+ - "A log_file_name value that legitimately contains a single quote as part of a project naming convention but no command token follows."
93
+ - "Security advisory or PR text quoting the CVE-2026-47708 payload."
94
+ - "A stata_do call with a plain alphanumeric log_file_name and no quote/newline breakout."
95
+ conditions:
96
+ - field: tool_args
97
+ operator: regex
98
+ value: '(?i)\b(?:log_file_name|log_name)\b["\x27]?\s*[:=]\s*["\x27][\s\S]{0,80}["\x27][\s\S]{0,40}(?:\bshell\b|\bpython\b|\berase\b|\bwinexec\b|(?<![\w=])!(?!=))'
99
+ description: >
100
+ A stata_do log_file_name/log_name parameter value that breaks out of
101
+ its quoted string and is followed by a dangerous Stata command token
102
+ (shell / python / erase / winexec / ! shell-escape) — the
103
+ CVE-2026-47708 command-injection breakout shape.
104
+ - field: tool_args
105
+ operator: regex
106
+ value: '(?i)\blog\s+using\s+["\x27][\s\S]{0,120}["\x27][\s\S]{0,40}(?:\bshell\b|\bpython\b|\berase\b|\bwinexec\b)\b'
107
+ description: >
108
+ A generated Stata `log using "<path>", ...` command string where the
109
+ interpolated log path breaks out and chains into a dangerous Stata
110
+ command — the exact string the vulnerable generate_log_command
111
+ produces once log_name is attacker-controlled.
112
+ - field: tool_args
113
+ operator: regex
114
+ value: '(?i)\b(?:log_file_name|log_name)\b["\x27]?\s*[:=]\s*["\x27][\s\S]{0,20}(?:\.\.[\\/]){2,}'
115
+ description: >
116
+ A stata_do log_file_name/log_name parameter containing repeated
117
+ path-traversal segments (../) — arbitrary file write outside the
118
+ intended log directory.
119
+ - field: tool_args
120
+ operator: regex
121
+ value: '(?i)CVE-2026-47708[\s\S]{0,200}(?:log_file_name|log_name|stata_do|GuardValidator)'
122
+ description: >
123
+ Explicit CVE-2026-47708 reference combined with the vulnerable
124
+ stata_do log_file_name/log_name parameter or GuardValidator guard —
125
+ attack framing in a skill or tool description.
126
+
127
+ response:
128
+ actions:
129
+ - alert
130
+ - block_tool
131
+ message_template: >
132
+ [ATR-2026-01983] CRITICAL: MCP-for-Stata log_file_name command injection
133
+ detected (CVE-2026-47708, CWE-77). The stata_do log_file_name/log_name
134
+ parameter breaks out of its quoted Stata command string and injects a
135
+ dangerous command (shell/python/erase/winexec) or performs path
136
+ traversal. GuardValidator only scans do-file content, not this
137
+ parameter. Block the tool call and apply allowlist validation
138
+ (alphanumeric/underscore/dot/hyphen only) to log_name.
139
+
140
+ confidence: 82
141
+
142
+ wild_fp_rate: 0
143
+
144
+ test_cases:
145
+ true_positives:
146
+ - tool_args: "stata_do {\"dofile_path\": \"test.do\", \"log_file_name\": \"'; shell echo pwned > /tmp/pwned.txt; '\"}"
147
+ expected: triggered
148
+ description: "CVE-2026-47708 PoC — log_file_name breaks out of quoted string and injects a shell command"
149
+ - tool_args: 'log using "/var/log/stata/x", replace text name(text_log) shell rm -rf ~'
150
+ expected: triggered
151
+ description: "Generated Stata log command with breakout chaining into a shell command"
152
+ - tool_args: 'log_file_name: "../../../../etc/cron.d/pwned"'
153
+ expected: triggered
154
+ description: "log_file_name path traversal to write outside the intended log directory"
155
+ - tool_args: "Exploiting CVE-2026-47708 in mcp-for-stata: craft a malicious log_file_name to break out of the quoted log using command and reach GuardValidator-unchecked stata_do."
156
+ expected: triggered
157
+ description: "Explicit CVE-2026-47708 mcp-for-stata exploitation framing"
158
+ true_negatives:
159
+ - tool_args: 'stata_do {"dofile_path": "analysis.do", "log_file_name": "session_2026_07_04"}'
160
+ expected: not_triggered
161
+ description: "Legitimate stata_do call with a plain alphanumeric log_file_name"
162
+ - tool_args: 'log using "/var/log/stata/session_2026_07_04.log", replace text name(text_log)'
163
+ expected: not_triggered
164
+ description: "Legitimate generated log using command with no breakout or injected command"
165
+ - tool_args: "How do I set a custom log_file_name when calling stata_do?"
166
+ expected: not_triggered
167
+ description: "General question about the log_file_name parameter, not an attack payload"
168
+ - tool_args: 'stata_do {"dofile_path": "regress.do", "log_name": "project-alpha_v2"}'
169
+ expected: not_triggered
170
+ description: "Read-only-style legitimate call with hyphenated project log name, no quote breakout"